QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#528882 | #4839. Smaller LCA | Nanani_fan# | WA | 1843ms | 539696kb | C++20 | 3.6kb | 2024-08-24 00:09:38 | 2024-08-24 00:09:39 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//注意Sum和cnt的区别
const int maxn = 3e5+10; // 数据范围
ll ans[maxn];
int n, cnt;
int sum[maxn*150], ls[maxn*150], rs[maxn*150];
// 用法:update(root, 1, n, x, f); 其中 x 为待修改节点的编号
void update(int& p, int L, int R, int x, int f) { // 引用传参
if (!p) p = ++cnt; // 当结点为空时,创建一个新的结点
if (L == R) {
sum[p] += f;
return;
}
int m = L + ((R - L) >> 1);
if (x <= m)
update(ls[p], L, m, x, f);
else
update(rs[p], m + 1, R, x, f);
sum[p] = sum[ls[p]] + sum[rs[p]]; // pushup
}
// 用法:query(root, 1, n, l, r);
int query(int p, int L, int R, int l, int r) {
if (!p) return 0; // 如果结点为空,返回 0
if (L >= l && R <= r) return sum[p];
int m = L + ((R - L) >> 1), ans = 0;
if (l <= m) ans += query(ls[p], L, m, l, r);
if (r > m) ans += query(rs[p], m + 1, R, l, r);
return ans;
}
int merge(int a, int b, int l, int r) {
if (!a) return b;
if (!b) return a;
if (l == r) {
sum[a]+=sum[b];
return a;
}
int mid = (l + r) >> 1;
ls[a] = merge(ls[a], ls[b], l, mid);
rs[a] = merge(rs[a], rs[b], mid + 1, r);
sum[a]=sum[ls[a]]+sum[rs[a]];
return a;
}
vector<int> ve[maxn];
int L[maxn],R[maxn],dfn;
int Sum[maxn];
void add(int l,int r,int x){
// cout<<"l="<<l<<" r="<<r<<" x="<<x<<endl;
Sum[l]+=x;
Sum[r+1]-=x;
}
int dep[maxn],f[21][maxn];
void dfs1(int x,int h)
{
L[x]=++dfn;
dep[x]=dep[h]+1;
for(int i=0;i<=19;i++)
f[i+1][x]=f[i][f[i][x]];
for(auto it:ve[x])if(it!=h){
f[0][it]=x;
dfs1(it,x);
}
R[x]=dfn;
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--)
{
if(dep[f[i][x]]>=dep[y]) x=f[i][x];
if(x==y) return x;
}
for(int i=20;i>=0;i--)
if(f[i][x]!=f[i][y])
x=f[i][x],y=f[i][y];
return f[0][x];
}
int getson(int x,int y){
assert(L[y]>=L[x]&&R[y]<=R[x]);
for(int i=20;i>=0;i--)if(dep[f[i][y]]>dep[x])y=f[i][y];
return y;
}
vector<int> ad[maxn];
vector<pair<int,int>>era[maxn];
int dfs(int x,int h){
int rt=0;
for(auto it:ve[x])if(it!=h){
int g=dfs(it,x);
int t=query(g,1,n,x,n);
add(L[x],R[x],t);
add(L[it],R[it],-t);
rt=merge(rt,g,1,n);
// cout<<"x="<<x<<" h="<<h<<" it="<<it<<" t="<<t<<endl;
}
for(auto [p,q]:era[x])if(x<=p*q){
add(1,n,1);add(L[x],R[x],-1);
if(q==x)swap(p,q);
update(rt,1,n,p*q,-2);
// cout<<"x="<<x<<" it="<<p*q<<" -2"<<endl;
if(p==x)add(L[x],R[x],-1);
if(p!=x)add(L[x],R[x],-1);
}
for(auto it:ad[x]){
update(rt,1,n,it,1);
// cout<<"x="<<x<<" it="<<it<<" 1"<<endl;
add(L[x],R[x],1);
}
return rt;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<n;i++){
int x,y;cin>>x>>y;
// int x=i+1,y=rand()%(i)+1;
ve[x].push_back(y);
ve[y].push_back(x);
}
ll all=0;
dfs1(1,0);
for(int i=1;i<=n;i++){
all++;
for(int j=i+1;j<=n;j++)if((ll)i*j<=n){
ad[i].push_back(i*j);
ad[j].push_back(i*j);
int l=lca(i,j);
era[l].emplace_back(i,j);
}
else {all+=n-j+1;break;}
}
dfs(1,0);
for(int i=1;i<=n;i++)Sum[i]+=Sum[i-1];
for(int i=1;i<=n;i++){
cout<<all+Sum[L[i]]<<"\n";
// cout<<all<<" "<<Sum[L[i]]<<endl;
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 3ms
memory: 32304kb
input:
5 1 2 4 2 2 5 3 5
output:
15 15 15 15 14
result:
ok 5 number(s): "15 15 15 15 14"
Test #2:
score: -100
Wrong Answer
time: 1843ms
memory: 539696kb
input:
300000 40632 143306 32259 40632 225153 143306 269774 225153 289668 40632 191636 269774 85717 191636 58564 191636 156509 143306 289939 40632 247103 269774 40257 40632 98149 289668 142277 143306 291616 40257 46813 225153 56324 143306 277154 142277 53903 289668 114266 32259 152231 58564 241151 152231 4...
output:
45000862883 44999824879 44999836967 44999835990 44999076476 44999697884 44999439666 44999160080 44999050820 44999148581 44999824160 44999155995 44999295007 44999516751 44999621211 44999561489 44999139350 44999347509 44999358431 44999143157 44999772108 44999343162 44999554742 44999157149 44999890827 ...
result:
wrong answer 1st numbers differ - expected: '44999437117', found: '45000862883'