只有部分題解
練習賽
T2
自然還是要簡單考慮了
0~n-1的排列,考慮相對的大小
我們先考慮對於前三個:a,b,c
詢問a,b,詢問b,c,再詢問a,b,c
發現,如果三個知道兩個,那么第三個可以唯一確定
所以分情況討論一下:
1.a>b,不妨欽定a=n-1,然后得到a,b,c的值,再詢問(c,d),(b,c,d)。。。就可以得到所有的值
2.a<b,不妨欽定a=0,然后得到a,b,c的值,再詢問(c,d),(b,c,d)。。。就可以得到所有的值
這里,由於a的值是欽定的,可能得到某個值是負數或者是大於n-1的,那么可以整體上下平移,得到最后的序列
最后的序列中,只要滿足0在n-1左邊,並且是一個0~n-1的排列,那么就是答案(顯然只有一個)
T3
可以說是經典的冒泡排序問題!
自然要抓住本質
我們考慮對於一個ai,它歸位的次數就是它前面比它大的數的個數f[i]
證明:前面比它大的數,一次最多沉底一個,然而對於自己往后沉,在后面的bi前比bi小的數那里會考慮到的
所以就是max(f[i])
修改怎么辦?
樹套樹!
兩個logn成功T飛
發現,如果i<j並且ai>aj,那么f[i]一定小於f[j],這樣的i是沒有用的
把剛才的定義變一下:
然后動態開點權值線段樹維護即可(離線離散化也可以不動態開點)
T4
更優用bfs O(n^2)判斷(反正提交答案)
Day1
T1
首先,首字母只有一次
詢問AB,如果長度>=1,就是A或者B,再問一次。否則是X或者Y,再問一次。——2次
后面怎么辦?
這個長度不超過4n有點意思
首先一定要滿足前綴是S,所以確定的前i-1位必須都有
看來要復制4份,不妨首字母是A
暴力枚舉下一個:[A....BX][A....BY][A.....BB][A....X]
由於首字母只有一次,得到的一定是四個子串的最大匹配長度
如果多了2,就是B;多了1,就是X;不變,就是Y
1次確定一位。
最后一個,需要2次確定,嘗試X,再嘗試Y。
總共:2+(n-2)+2=n+2次
T2
貼課件:
(這個暫時不懂怎么找那H+W個矩形)
聯通塊的轉化,然后利用點數-邊數最少是1,所以維護最小值和最小值個數即可
聯通塊的轉化很神仙啊
啟示我們,對於一些不好處理的東西,我們提取特征值記錄
這里還利用了最小是1,而1恰好是合法的這一個trick
具體實現的話:
每次把原來的貢獻減掉,新來的再加上
T3
kruscal重構樹石錘了
把邊權看成min(idx,idy)(最大生成樹)或者max(idx,idy)(最小生成樹)
就是判斷兩個kruscal重構樹對應的子樹,有沒有交點即可
考慮把每個端點看成二維平面上的一個點,橫坐標是第一個重構樹的位置編號,縱坐標是第二個重構樹位置的編號
有無交點,就是統計(l1,l2,r1,r2)這個矩形中有沒有點
二維數點問題
離線掃描線+樹狀數組解決
(ps:強制在線的話可以用主席樹)
代碼:

#include<bits/stdc++.h> #define reg register int #define il inline #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int M=400000+5; const int N=400000+5; const int inf=0x3f3f3f3f; int n,m,Q; struct edge{ int x,y; int val; }b[M]; bool cmp0(edge a,edge b){ return a.val<b.val; } bool cmp1(edge a,edge b){ return a.val>b.val; } int fafa[2*N]; struct kruskal{ struct node{ int nxt,to; }e[2*N]; int hd[2*N],cnt; int fin(int x){ return fafa[x]==x?x:fafa[x]=fin(fafa[x]); } void add(int x,int y){ e[++cnt].nxt=hd[x]; e[cnt].to=y; hd[x]=cnt; } int tot; void build(int typ){ for(reg i=1;i<=n;++i){ if(typ) val[i]=inf; else val[i]=-inf; } tot=n; for(reg i=1;i<=m;++i){ int k1=fin(b[i].x),k2=fin(b[i].y); // cout<<" edge "<<b[i].x<<" "<<b[i].y<<" :: "<<k1<<" "<<k2<<endl; if(k1!=k2){ ++tot; fafa[tot]=tot; fafa[k1]=tot; fafa[k2]=tot; val[tot]=b[i].val; add(tot,k1); add(tot,k2); } } } int l[N],r[N]; int val[N]; int fa[N][20]; int df; void dfs(int x){ // cout<<" xx "<<x<<endl; int son=0; r[x]=-inf;l[x]=inf; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; ++son; dfs(y); fa[y][0]=x; r[x]=max(r[x],r[y]); l[x]=min(l[x],l[y]); } if(!son){ l[x]=r[x]=++df; } } void pre(){ dfs(tot); for(reg j=1;j<=19;++j){ for(reg i=1;i<=tot;++i){ fa[i][j]=fa[fa[i][j-1]][j-1]; } } } int fin(int x,int lim,int typ){//beizeng go val int p=x; if(!typ){//go <=lim for(reg j=19;j>=0;--j){ if(fa[p][j]){ if(val[fa[p][j]]<=lim) p=fa[p][j]; } } return p; }else{//go >=lim for(reg j=19;j>=0;--j){ if(fa[p][j]){ if(val[fa[p][j]]>=lim) p=fa[p][j]; } } return p; } } }kt[2];//0:min tree;1:max tree; int num; struct po{ int x,y; bool friend operator <(po a,po b){ return a.x<b.x; } }p[N]; int ans[N]; int tot; struct que{ int id,x,typ,y1,y2; bool friend operator <(que a,que b){ return a.x<b.x; } }q[N*2]; struct binarytree{ int f[N]; void upda(int x){ for(;x<=n;x+=x&(-x)) f[x]++; } int query(int x){ int ret=0; for(;x;x-=x&(-x)) ret+=f[x]; return ret; } }t; int main(){ rd(n);rd(m);rd(Q); for(reg i=1;i<=m;++i){ rd(b[i].x);rd(b[i].y); ++b[i].x;++b[i].y;//warning!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! b[i].val=max(b[i].x,b[i].y); } sort(b+1,b+m+1,cmp0); for(reg i=1;i<=2*n;++i){ fafa[i]=i; } kt[0].build(0); kt[0].pre(); // cout<<" after build small "<<endl; for(reg i=1;i<=m;++i){ b[i].val=min(b[i].x,b[i].y); } sort(b+1,b+m+1,cmp1); for(reg i=1;i<=2*n;++i){ fafa[i]=i; } kt[1].build(1); kt[1].pre(); int st,nd,L,R; for(reg i=1;i<=Q;++i){ rd(st);rd(nd);rd(L);rd(R); ++L;++R; ++st;++nd;//warning!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! int ptr=kt[1].fin(st,L,1); q[++tot].id=i; q[tot].y1=kt[1].l[ptr]; q[tot].y2=kt[1].r[ptr]; q[++tot].id=i; q[tot].y1=kt[1].l[ptr]; q[tot].y2=kt[1].r[ptr]; ptr=kt[0].fin(nd,R,0); q[tot-1].x=kt[0].l[ptr]-1; q[tot].x=kt[0].r[ptr]; q[tot-1].typ=-1; q[tot].typ=1; } sort(q+1,q+tot+1); for(reg i=1;i<=n;++i){ p[i].x=kt[0].l[i]; p[i].y=kt[1].l[i]; } sort(p+1,p+n+1); int ptp=1,ptq=1; for(reg i=1;i<=n;++i){ while(ptp<=n&&p[ptp].x<i) ++ptp; if(p[ptp].x==i){ while(ptp<=n&&p[ptp].x==i){ t.upda(p[ptp].y); ++ptp; } } while(ptq<=tot&&q[ptq].x<i) ++ptq; if(q[ptq].x==i){ while(ptq<=tot&&q[ptq].x==i){ ans[q[ptq].id]+=q[ptq].typ*(t.query(q[ptq].y2)-t.query(q[ptq].y1-1)); ++ptq; } } } for(reg i=1;i<=Q;++i){ puts(ans[i]?"1":"0"); } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2019/2/10 15:50:00 */