Submission #1005647

#TimeUsernameProblemLanguageResultExecution timeMemory
1005647modwweTourism (JOI23_tourism)C++17
100 / 100
3245 ms51500 KiB
/**https://www.instagram.com/_modwwe/ #pragma GCC optimize("Ofast,unroll-loops") //#pragma GCC target("avx2,bmi,bmi2") #include<bits/stdc++.h> //#define int long long //#define ll long long #define down cout<<'\n'; #define NHP ios_base::sync_with_stdio(0);cout.tie(0);cin.tie(0); #define modwwe int t;cin>>t; while(t--) #define bit(i,j) (i>>j&1) #define sobit(a) __builtin_popcountll(a) #define task "test" #define fin(x) freopen(x".inp","r",stdin) #define fou(x) freopen(x".out","w",stdout) #define pb push_back #define checktime cerr << (double)clock() / CLOCKS_PER_SEC * 1000 << " ms"; using namespace std; void phongbeo(); const int mod2=1e9+7; const int mod1=998244353; struct icd { int a,b; }; struct ib { int a; int b; }; struct ic { int a,b,c; }; struct id { int a,c; }; struct ie { int a,b,c, d,e,f; }; int n,m,s1,s2,s4,s3,sf,k,r,mid,s5,s6,mx,s7,s8,s9,mx2,res,dem2=0,dem=0,l; int i,s10,s12; int el=29; main() { #ifndef ONLINE_JUDGE fin(task),fou(task); #endif ios_base::sync_with_stdio(0);cout.tie(0);cin.tie(0); /// cin>>s1; // modwwe phongbeo(); checktime } int t[400007]; int depth[100007]; ic a[100007]; int c[100007]; ib euler[100007]; int d[100007]; int st[17][100007]; int ans[100007]; int S; int b[100007]; int sl[100007]; vector<int> v[100007]; int e[100007]; int pre[100007]; int nxt[100007]; bool cmp(ic a,ic b) { if(a.a / S != b.a / S) return (a.a < b.a); else if(!((a.a / S) & 1)) return (a.b < b.b); else return (a.b > b.b); } void upd(int node,int l,int r,int l1,int r1,int cc) { if(l>=l1&&r<=r1) { if(cc==1) t[node]=l; else t[node]=0; return; } int mid=l+r>>1; if(mid>=r1) upd(node<<1,l,mid,l1,r1,cc); else upd(node<<1|1,mid+1,r,l1,r1,cc); t[node]=max(t[node<<1],t[node<<1|1]); } int get1(int node,int l,int r,int l1,int r1) { if(l>r1||r<l1) return 0; if(l>=l1&&r<=r1) return t[node]; int mid=l+r>>1; int ss3=0; if(t[node<<1|1]!=0) ss3=get1(node<<1|1,mid+1,r,l1,r1); if(ss3!=0) return ss3; else return get1(node<<1,l,mid,l1,r1); } void dfs(int x,int y) { st[0][x]=y; depth[x]=depth[y]+1; euler[x].a=++dem; mx=max(mx,depth[x]); c[dem]=x; for(auto f:v[x]) if(f!=y) dfs(f,x); euler[x].b=dem; } int lca(int x,int y,int cc) { if(x==0||x==n+1||y==0||y==n+1) return 1; if(depth[x]<depth[y]) swap(x,y),cc=0; int ss=depth[x]-depth[y]-1; if(ss>=0) for(int j=0; j<mx; ++j) if(bit(ss,j)) x=st[j][x]; if(st[0][x]==y) return x; if(ss!=-1) x=st[0][x]; for(int j=mx-1; j>=0; --j) if(st[j][x]!=st[j][y]) x=st[j][x],y=st[j][y]; if(cc==0) return y; else return x; } int lca2(int x,int y) { if(x==0 )return y; if(y==0 )return x; if(depth[x]<depth[y]) swap(x,y); int ss=depth[x]-depth[y]; if(ss!=0) for(int j=0; j<mx; ++j) if(bit(ss,j)) x=st[j][x]; if(x==y) return x; for(int j=mx-1; j>=0; --j) if(st[j][x]!=st[j][y]) x=st[j][x],y=st[j][y]; return st[0][x]; } /*void build2(int node,int l,int r) { if(l==r) { lz[node]=b[l]; return; } int mid=l+r>>1; build2(node<<1,l,mid); build2(node<<1|1,mid+1,r); lz[node]=lca2(lz[node<<1],lz[node<<1|1]); } int get_lca(int node,int l,int r,int l1,int r1) { if(l>r1||r<l1) return 0; if(l>=l1&&r<=r1) return lz[node]; int mid=l+r>>1; return lca2(get_lca(node<<1,l,mid,l1,r1),get_lca(node<<1|1,mid+1,r,l1,r1)); } void add(int x) { s2=get1(1,1,n,1,euler[x].a); /// s3=get2(1,1,n,euler[x].a,n); sl[x]++; if(sl[x]==1) upd(1,1,n,euler[x].a,euler[x].a,1); if(d[x]!=0||sl[x]>1) return; s2=c[s2]; s3=nxt[s2]; pre[x]=s2; nxt[x]=s3; nxt[s2]=x; pre[s3]=x; //if(l==3&&x==1) cout<<s2<<" "<<s3<<" "<<x,down s2=lca(x,s2,1); s3=lca(x,s3,1); if(depth[s2]<depth[s3]) swap(s2,s3); if(depth[x]>=depth[s2]) { s4+=depth[x]-depth[s2]+1; d[x]=s2; e[s2]=x; } } void del(int x) {sl[x]--; if(sl[x]==0) upd(1,1,n,euler[x].a,euler[x].a,-1); s5=d[x]; //s2=get1(1,1,n,euler[s5].a,euler[x].a); //s3=get2(1,1,n,euler[x].a,euler[s5].b); if(sl[x]>=1) return; s2=pre[x]; s3=nxt[x]; nxt[s2]=s3; if(s3!=0) pre[s3]=s2; pre[x]=0; nxt[x]=0; s9=s2; if(d[x]==0)return; d[x]=0; e[s5]=0; s4-=(depth[x]-depth[s5]+1); s2=lca(s2,x,1); s3=lca(s3,x,1); if(max(depth[s2],depth[s3])<=depth[s5]) return; if(st[0][s2]==s9&&depth[s2]>=depth[s3]&&d[s2]==0) { s2=s9; s4+=depth[s2]-depth[s5]+1; d[s2]=s5; e[s5]=s2; return; } if(depth[s2]<depth[s3])swap(s2,s3); if(depth[s5]<depth[s2]) { s3=e[s2]; e[s2]=0; e[s5]=s3; d[s3]=s5; s4+=(depth[s2]-depth[s5]); } } void go(int x,int y) { while(r<y) { ++r; add(b[r]); } while(l>x) { --l; add(b[l]); //cout<<l<<" "<<s4,down } //cout<<s4<<" "<<x<<" "<<y,down while(l<x) { del(b[l]); ++l; } while(r>y) { del(b[r]); --r; } } #define getchar_unlocked getchar inline int scan(){ char c = getchar_unlocked(); int x = 0; while(c<'0'||c>'9'){ c=getchar_unlocked(); } while(c>='0'&&c<='9'){ x=(x<<1)+(x<<3)+c-'0'; c=getchar_unlocked(); } return x; } void phongbeo() { //cin>>n>>m>>k; n=scan(); m=scan(); k=scan(); S=sqrt(m); for(int i=1; i<n; ++i) l=scan(),r=scan(),v[l].pb(r),v[r].pb(l); dfs(1,0); mx=log2(mx)+1; if(mx>17) mx=17; for(int i=1; i<mx; ++i) for(int j=1; j<=n; ++j) st[i][j]=st[i-1][st[i-1][j]]; for(int i=1; i<=m; ++i) b[i]=scan(); for(int i=1; i<=k; ++i) a[i].a=scan(),a[i].b=scan(),a[i].c=i; sort(a+1,a+1+k,cmp); l=1; r=0; for(int i=1; i<=k; ++i) { go(a[i].a,a[i].b); s3=t[1]; s5=nxt[0]; s3=c[s3]; s3=lca2(s3,s5); ans[a[i].c]=s4+depth[1]-depth[s3]; } for(int i=1; i<=k; ++i) printf("%d",ans[i]), printf("\n"); } /* 8 8 2 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 6 4 3 5 2 4 7 2 8 1 2 */ #pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,bmi,bmi2") #include<bits/stdc++.h> using namespace std; // #define int long long #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define isz(x) ((int)x.size()) #define sumof(x) accumulate(all(x), 0ll) const int N=1e5+1, S=400, LG=18; struct Query{ int l, r, i; Query(int a=0, int b=0, int c=0): l(a), r(b), i(c){} bool operator<(const Query& x){ return l/S!=x.l/S?l<x.l:((l/S)&1?r<x.r:r>x.r); } } qq[N]; struct FenwickTree{ int n; vector<int> t; void init(int _n){ n=_n; t.assign(n+1, 0); } void update(int pos, int val){ for (int i=pos; i<=n; i+=i&(-i)) t[i]+=val; } int get(int pos){ int ans=0; for (int i=pos; i; i-=i&(-i)) ans+=t[i]; return ans; } int lower_bound(int val){ int ans=0; for (int i=16; i>=0; --i) if (ans+(1<<i)<=n && t[ans+(1<<i)]<val){ ans+=1<<i; val-=t[ans]; } return ans+1; } }; int n, m, q, a[N], tdfs, tin[N], tout[N], dep[N], ans[N], cnt[N], tour[N]; int tin2[N], tout2[N], tdfs2; pair<int, int> st[N*2][LG]; vector<int> g[N]; void dfs(int u, int p){ tin[u]=++tdfs; tin2[u]=++tdfs2; tour[tdfs2]=u; dep[u]=dep[p]+1; st[tdfs][0]={dep[u], u}; for (int v:g[u]) if (v!=p){ dfs(v, u); ++tdfs; st[tdfs][0]={dep[u], u}; } tout[u]=tdfs; tout2[u]=tdfs2; } void build(){ for (int k=1; k<LG; ++k) for (int i=1; i+(1<<k)-1<=tdfs; ++i) st[i][k]=min(st[i][k-1], st[i+(1<<(k-1))][k-1]); } int lca(int u, int v){ u=tin[u]; v=tin[v]; if (u>v) swap(u, v); int lg=__lg(v-u+1); return min(st[u][lg], st[v-(1<<lg)+1][lg]).second; } int distance(int u, int v){ return dep[u]+dep[v]-dep[lca(u, v)]*2; } namespace among{ struct SUS{ int prev_arr[N], next_arr[N]; int size; FenwickTree bit; int ans; int get_order(int x){ return bit.get(x); } int find_by_order(int i){ return bit.lower_bound(i); } int find_first(){ return bit.lower_bound(1); } int find_last(){ return bit.lower_bound(size); } void insert(int x){ if (size){ int i=get_order(x); int prev=i?find_by_order(i):find_last(); int next=next_arr[prev]; ans-=distance(tour[prev], tour[next]); ans+=distance(tour[prev], tour[x]); ans+=distance(tour[x], tour[next]); prev_arr[x]=prev; next_arr[prev]=x; prev_arr[next]=x; next_arr[x]=next; } bit.update(x, 1); if (!size){ prev_arr[x]=x; next_arr[x]=x; } ++size; } void erase(int x){ bit.update(x, -1); --size; if (size){ int prev=prev_arr[x]; int next=next_arr[x]; ans+=distance(tour[prev], tour[next]); ans-=distance(tour[prev], tour[x]); ans-=distance(tour[x], tour[next]); prev_arr[next]=prev; next_arr[prev]=next; } } } us; } void solve(){ #ifdef sus freopen("03-04.txt", "r", stdin); freopen("cf.out", "w", stdout); #endif cin >> n >> m >> q; for (int i=1; i<n; ++i){ int x, y; cin >> x >> y; g[x].push_back(y); g[y].push_back(x); } dfs(1, 0); build(); for (int i=1; i<=m; ++i) cin >> a[i]; for (int i=1; i<=q; ++i){ int x, y; cin >> x >> y; qq[i]={x, y, i}; } sort(qq+1, qq+q+1); int cl=1, cr=0; among::us.bit.init(n*2); for (int i=1; i<=q; ++i){ int l=qq[i].l, r=qq[i].r; while (l<cl){ --cl; if (!cnt[tin2[a[cl]]]) among::us.insert(tin2[a[cl]]); ++cnt[tin2[a[cl]]]; } while (r>cr){ ++cr; if (!cnt[tin2[a[cr]]]) among::us.insert(tin2[a[cr]]); ++cnt[tin2[a[cr]]]; } while (l>cl){ --cnt[tin2[a[cl]]]; if (!cnt[tin2[a[cl]]]) among::us.erase(tin2[a[cl]]); ++cl; } while (r<cr){ --cnt[tin2[a[cr]]]; if (!cnt[tin2[a[cr]]]) among::us.erase(tin2[a[cr]]); --cr; } ans[qq[i].i]=among::us.ans/2+1; } for (int i=1; i<=q; ++i) cout << ans[i] << '\n'; } int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); int ntests=1; // cin >> ntests; for (int i=1; i<=ntests; ++i) solve(); return 0; }

Compilation message (stderr)

tourism.cpp:150:1: warning: "/*" within comment [-Wcomment]
  150 | /*void build2(int node,int l,int r)
      |  
tourism.cpp:315:1: warning: "/*" within comment [-Wcomment]
  315 | /*
      |
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...