GDOI2018 涛涛摘苹果 [CDQ分治]
生活随笔
收集整理的這篇文章主要介紹了
GDOI2018 涛涛摘苹果 [CDQ分治]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門我會讓你知道哪里有題面嗎(逃
思路
顯然不能模擬蘋果下掉的過程,考慮計算每個蘋果對詢問的貢獻。
顯然一開始就有的蘋果可以看做第0天變出來的,于是只需要考慮變出來的蘋果了。
設當前詢問節點\(x\),時間為\(t_1\)天早上。
設考慮的蘋果一開始在\(t_2\)晚上從\(y\)節點上變了出來。
那么造成貢獻的條件就是
\[ t_2<t_1 \]
\[ dfn_x\leq dfn_y \leq low_x \]
\[ dep_y+t_2\geq dep_x +t_1-1 \]
顯然這是個三維偏序,裸上CDQ分治即可。
注意同一天早晚的區別,按時間sort時要小心。
代碼
#include<bits/stdc++.h> clock_t t=clock(); namespace my_std{using namespace std;#define pii pair<int,int>#define fir first#define sec second#define MP make_pair#define rep(i,x,y) for (int i=(x);i<=(y);i++)#define drep(i,x,y) for (int i=(x);i>=(y);i--)#define go(x) for (int i=head[x];i;i=edge[i].nxt)#define templ template<typename T>#define sz 101010typedef long long ll;typedef double db;mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}templ inline void read(T& t){t=0;char f=0,ch=getchar();double d=0.1;while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}t=(f?-t:t);}template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}char sr[1<<21],z[20];int C=-1,Z=0;inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}inline void print(register int x){if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++C]=z[Z],--Z);sr[++C]='\n';}void file(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);#endif}inline void chktime(){#ifndef ONLINE_JUDGEcout<<(clock()-t)/1000.0<<'\n';#endif}#ifdef modll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}ll inv(ll x){return ksm(x,mod-2);}#elsell ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}#endif // inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;} } using namespace my_std;int n,m,Q,M; ll a[sz]; struct hh{int t,nxt;}edge[sz<<1]; int head[sz],ecnt; void make_edge(int f,int t) {edge[++ecnt]=(hh){t,head[f]};head[f]=ecnt;edge[++ecnt]=(hh){f,head[t]};head[t]=ecnt; }int dfn[sz],low[sz],dep[sz],T; void dfs(int x,int fa) {dfn[x]=++T;dep[x]=dep[fa]+1;go(x) if(edge[i].t!=fa) dfs(edge[i].t,x);low[x]=T; }struct hhh {int type; // 0:modify,1:queryint p,d;ll w; // dfn:p,dep:d,+=wint l,r,D,id; // dfn:[l,r],dep:\geq Dint ti; // time }q[sz<<2]; inline bool cmp(const hhh &x,const hhh &y) {if (x.type!=y.type) return x.type;if (x.type==0) return x.d>y.d;return x.D>y.D; } inline bool cmpt(const hhh &x,const hhh &y) {if (x.type==y.type) return x.ti<y.ti;else if (x.type) return x.ti<=y.ti;return x.ti<y.ti; } ll ans[sz];ll tr[sz]; void add(int x,ll w){while (x<=n) tr[x]+=w,x+=(x&(-x));} ll query(int x){ll ret=0;while (x) ret+=tr[x],x-=(x&(-x));return ret;}void solve(int l,int r) {if (l==r) return;int mid=(l+r)>>1;solve(l,mid);solve(mid+1,r);int p=l;rep(i,mid+1,r) if (q[i].type){while (p<=mid){if (q[p].type) ++p;else if (q[p].d>=q[i].D) add(q[p].p,q[p].w),++p;else break;}ans[q[i].id]+=query(q[i].r)-query(q[i].l-1);}rep(i,l,p-1) if (!q[i].type) add(q[i].p,-q[i].w);sort(q+l,q+r+1,cmp); }int main() {file();read(n,m,Q);rep(i,1,n) read(a[i]);int x,y,z;rep(i,1,n-1) read(x,y),make_edge(x,y);dfs(1,0);rep(i,1,n) q[++M]=(hhh){0,dfn[i],dep[i],a[i],0,0,0,0,0};while (m--) read(x,y,z),q[++M]=(hhh){0,dfn[y],dep[y]+x,z,0,0,0,0,x};rep(i,1,Q) read(z,x),q[++M]=(hhh){1,0,0,0,dfn[x],low[x],dep[x]+z-1,i,z};sort(q+1,q+M+1,cmpt);solve(1,M);rep(i,1,Q) printf("%lld\n",ans[i]);return 0; }轉載于:https://www.cnblogs.com/p-b-p-b/p/10440578.html
總結
以上是生活随笔為你收集整理的GDOI2018 涛涛摘苹果 [CDQ分治]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知识图谱构建摸索
- 下一篇: Verilog左移位