Digital_Sunrise @ 2024-07-09 10:29:10
开 O2
就 TLE
不开就 MLE
试过在不开的情况下只把一点点变量改成 long long
没什么用
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int _ = 3e5 + 5;
inline int read()
{
int w = 1,f = 0;
char c = getchar();
while(c < '0' or c > '9'){if(c == '-') w = -1;c = getchar();}
while(c >= '0' and c <= '9'){f = f * 10 + c - '0';c = getchar();}
return w * f;
}
struct node
{
int l,r,ls,rs,sum;
node(){l = r = ls = rs = sum = 0;}
node(int _l,int _r,int _ls,int _rs,int _sum):l(_l),r(_r),ls(_ls),rs(_rs),sum(_sum){}
}a[_ << 5];
int n,q;
vector <int> G[_];
int siz[_],dep[_],dfn[_],_dfn;
int init[_],cnt,rt[_];
void dfs(int u,int fa)
{
// cout << "FUCKING " << u << " " << fa << endl;
dep[u] = dep[fa] + 1;
dfn[u] = ++_dfn;
siz[u] = 1;
for(int v : G[u])
{
if(v == fa)
continue;
dfs(v,u);
siz[u] += siz[v];
}
}
int build(int l,int r)
{
int k = ++cnt;
a[k].l = l,a[k].r = r;
if(l == r) return k;
int mid = (l + r) >> 1;
a[k].ls = build(l,mid);
a[k].rs = build(mid + 1,r);
return k;
}
int update(int pre,int x,int y)
{
int k = ++cnt;
a[k] = a[pre];
if(a[k].l == a[k].r)
{
a[k].sum += y;
return k;
}
int mid = (a[k].l + a[k].r) >> 1;
if(x <= mid)
a[k].ls = update(a[k].ls,x,y);
if(x > mid)
a[k].rs = update(a[k].rs,x,y);
a[k].sum = a[a[k].ls].sum + a[a[k].rs].sum;
return k;
}
int query(int k,int l,int r)
{
// if(k == 0)
// exit(0);
// cout << k << " " << a[k].l << " " << a[k].r << endl;
if(a[k].l >= l and a[k].r <= r)
return a[k].sum;
int mid = (a[k].l + a[k].r) >> 1,sum = 0;
if(l <= mid)
sum += query(a[k].ls,l,r);
if(r > mid)
sum += query(a[k].rs,l,r);
return sum;
}
signed main()
{
n = read();
q = read();
for(int i = 1;i < n;i++)
{
int u,v;
u = read();
v = read();
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
for(int i = 1;i <= n;i++)
init[dfn[i]] = i;
//_______________________________
// cout << "dfn: ";
// for(int i = 1;i <= n;i++)
// cout << dfn[i] << " ";
// cout << endl << "init:";
// for(int i = 1;i <= n;i++)
// cout << init[i] << " ";
// cout << endl;
//_______________________________
rt[0] = build(1,n);
for(int i = 1;i <= n;i++)
rt[i] = update(rt[i - 1],dep[init[i]],siz[init[i]] - 1)/*,printf("FUCKing : %d - > %d \n",i,query(rt[i],1,4))*/;
while(q--)
{
int p = read(),k = read(),ans = 0;
ans += min(dep[p] - 1,k) * (siz[p] - 1);
// cout << "FUCK1 " << query(rt[dfn[p] + siz[p] - 1],1,4) << endl;
// cout << "FUCK2 " << query(rt[dfn[p]],1,4) << endl;
ans += query(rt[dfn[p] + siz[p] - 1],dep[p] + 1,dep[p] + k);
ans -= query(rt[dfn[p]], dep[p] + 1,dep[p] + k);//bug : dep[p + 1];
printf("%lld\n",ans);
}
return 0;
}
by Kapo_Hisy @ 2024-07-09 10:41:47
用define卡O3+快写+变量参数不用修改的用const+ans修改那一段合并一下。
可能会有加速(但不多)。
@Digital_Sunrise
by Digital_Sunrise @ 2024-07-09 10:49:31
@Kapo_Hisy
O3 被 OJ 拒收了。。
by Kapo_Hisy @ 2024-07-09 10:55:05
#define optimize qwq
#pragma GCC qwq(3)
我平时卡常用这个没问题的呀,奇怪了。@Digital_Sunrise
by Kapo_Hisy @ 2024-07-09 10:56:24
这好像不是RemoteJudge,似乎是没问题的,我有些P前缀题目卡常这样写似乎没问题。
by Digital_Sunrise @ 2024-07-09 11:04:04
@Kapo_Hisy 大佬能不能帮我分析一下
6年前有一个前辈通过加入了 query
函数第一行的特判从95改到了AC
ll query(int id1,int id2,int l,int r,int ql,int qr){
if(ql>qr) return 0;
if(l==ql&&r==qr) return t[id2].val-t[id1].val;
int mid=(l+r)/2;
if(qr<=mid) return query(t[id1].lch,t[id2].lch,l,mid,ql,qr);
else if(ql>mid) return query(t[id1].rch,t[id2].rch,mid+1,r,ql,qr);
else return query(t[id1].lch,t[id2].lch,l,mid,ql,mid)+query(t[id1].rch,t[id2].rch,mid+1,r,mid+1,qr);
}
但是我的写法似乎和主流不同,所以我并不知道我的 query
有没有问题、怎么改
这是我的:
ll query(int k,int l,int r)
{
// if(k == 0)
// exit(0);
// cout << k << " " << a[k].l << " " << a[k].r << endl;
if(a[k].l >= l and a[k].r <= r)
return a[k].sum;
int mid = (a[k].l + a[k].r) >> 1;
ll sum = 0;
if(l <= mid)
sum += query(a[k].ls,l,r);
if(r > mid)
sum += query(a[k].rs,l,r);
return sum;
}
by Kapo_Hisy @ 2024-07-09 11:06:28
@Digital_Sunrise 不好意思,我看主站点进来的,我不会主席树(逃)主要是我看(水)一下如何卡过(卡常方法)
by Kapo_Hisy @ 2024-07-09 11:07:08
后面的部分基本一致,就多了一个判断。
by Kapo_Hisy @ 2024-07-09 11:10:03
第一个特判明显是对的,但不过加上去因该是因为有可能数据会卡到l>r的情况
by Digital_Sunrise @ 2024-07-09 12:47:05
先给解决方法
query
中加入 k == 0
的特判
如果不是我这种解法就加入 ql > qr
的特判