考试T3的思路很巧妙,题目要求是严格的1~k,其余方案都是非法的,所以用哈希映射一下。
记录一些思路:柯多莉树(怎么也卡不掉),%%%remarkable就是用个set维护区间,统计的时候暴力扫,不然就直接合并/分裂。
线段树分治,维护一棵维护原序列的线段树和维护ID的时间的线段树,然后在原序列的线段树里搜索,多减减枝就行了。
问题有多个限制条件的时候,可以用线段树分治。
1 #include2 #include 3 #include 4 #define N 70005 5 using namespace std; 6 int ans[N],top,s[N][6],MX,st[N],ed[N],n,m; 7 struct tree{ 8 int d[N],top[N],sz[N],son[N],f[N]; 9 int head[N],to[N<<1],nxt[N<<1],cnt; 10 inline void Add(int u,int v) 11 { 12 to[++cnt]=v; 13 nxt[cnt]=head[u]; 14 head[u]=cnt; 15 } 16 void dfs1(int x,int fa) 17 { 18 sz[x]=1; 19 for(int i=head[x];i;i=nxt[i]) 20 { 21 int y=to[i]; 22 if(y==fa) continue; 23 d[y]=d[x]+1; 24 dfs1(y,x); 25 sz[x]+=sz[y]; 26 f[y]=x; 27 if(sz[y]>sz[son[x]]) son[x]=y; 28 } 29 } 30 void dfs2(int x,int fa,int xf) 31 { 32 top[x]=xf; 33 for(int i=head[x];i;i=nxt[i]) 34 { 35 if(to[i]==fa) continue; 36 if(son[x]==to[i]) dfs2(to[i],x,xf); 37 else dfs2(to[i],x,to[i]); 38 } 39 } 40 inline int dis(int a,int b) 41 { 42 int fa=top[a],fb=top[b],tmp=d[a]+d[b]; 43 while(fa!=fb) 44 { 45 if(d[fa]<d[fb]) swap(a,b),swap(fa,fb); 46 a=f[fa];fa=top[a]; 47 } 48 if(d[a]>d[b]) swap(a,b); 49 return tmp-2*d[a]; 50 } 51 }R; 52 struct BCJ{ 53 int f[N],id[N][2],len[N],sz[N]; 54 int find(int x){if(f[x]==x)return x;return find(f[x]);} 55 void merge(register int a,register int b) 56 { 57 int fa=find(a),fb=find(b),tmp,tmp1,tmp2; 58 if(sz[fa]<sz[fb]) 59 { 60 s[++top][0]=fa,s[top][1]=fb,s[top][2]=id[fb][0],s[top][3]=id[fb][1],s[top][4]=len[fb],s[top][5]=sz[fb]; 61 f[fa]=fb;int mx=0,id1,id2;sz[fb]+=sz[fa]; 62 if(len[fa]>len[fb]) mx=len[fa],id1=id[fa][0],id2=id[fa][1]; 63 else mx=len[fb],id1=id[fb][0],id2=id[fb][1]; 64 tmp1=id[fa][0],tmp2=id[fb][0];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 65 tmp1=id[fa][0],tmp2=id[fb][1];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 66 tmp1=id[fa][1],tmp2=id[fb][0];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 67 tmp1=id[fa][1],tmp2=id[fb][1];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 68 len[fb]=mx,id[fb][0]=id1,id[fb][1]=id2; 69 MX=max(MX,mx); 70 } 71 else 72 { 73 s[++top][0]=fb,s[top][1]=fa,s[top][2]=id[fa][0],s[top][3]=id[fa][1],s[top][4]=len[fa],s[top][5]=sz[fa]; 74 f[fb]=fa;int mx=0,id1,id2;sz[fa]+=sz[fb]; 75 if(len[fa]>len[fb]) mx=len[fa],id1=id[fa][0],id2=id[fa][1]; 76 else mx=len[fb],id1=id[fb][0],id2=id[fb][1]; 77 tmp1=id[fa][0],tmp2=id[fb][0];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 78 tmp1=id[fa][0],tmp2=id[fb][1];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 79 tmp1=id[fa][1],tmp2=id[fb][0];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 80 tmp1=id[fa][1],tmp2=id[fb][1];tmp=R.dis(tmp1,tmp2);if(tmp>mx) mx=tmp,id1=tmp1,id2=tmp2; 81 len[fa]=mx,id[fa][0]=id1,id[fa][1]=id2; 82 MX=max(MX,mx); 83 } 84 return ; 85 } 86 }E; 87 struct Segment_tree{ 88 vector<int> cs[N<<2]; 89 #define ls k<<1 90 #define rs k<<1|1 91 void insert(int k,int l,int r,int gl,int gr,int id) 92 { 93 if(l>=gl&&r<=gr) 94 { 95 cs[k].push_back(id); 96 return ; 97 } 98 int mid=l+r>>1; 99 if(gl<=mid) insert(ls,l,mid,gl,gr,id); 100 if(gr>mid) insert(rs,mid+1,r,gl,gr,id); 101 } 102 void dfs(int k,int l,int r) 103 { 104 int now=top,tmp=MX; 105 for(register int i=0;i )E.merge(st[cs[k][i]],ed[cs[k][i]]); 106 if(l==r) ans[l]=MX; 107 else dfs(ls,l,l+r>>1),dfs(rs,(l+r>>1)+1,r); 108 MX=tmp; 109 while(top!=now) E.f[s[top][0]]=s[top][0], 110 E.len[s[top][1]]=s[top][4],E.id[s[top][1]][0]=s[top][2],E.id[s[top][1]][1]=s[top][3],E.sz[s[top][1]]=s[top][5],top--; 111 } 112 }T; 113 struct main{ 114 inline int read() 115 { 116 int x=0;char c=getchar(); 117 while(c<'0'||c>'9') c=getchar(); 118 while(c>='0'&&c<='9') x=x*10+c-48,c=getchar(); 119 return x; 120 } 121 inline void work() 122 { 123 n=read(),m=read(); 124 for(register int i=1;i<=n;i++) E.f[i]=E.id[i][0]=E.id[i][1]=i,E.sz[i]=1; 125 for(register int i=1,a,b,c,d;i ) 126 st[i]=read(),ed[i]=read(),c=read(),d=read(),R.Add(st[i],ed[i]),R.Add(ed[i],st[i]),T.insert(1,1,n,c,d,i); 127 R.dfs1(1,0);R.dfs2(1,0,1); 128 T.dfs(1,1,n); 129 while(m--) printf("%d\n",ans[read()]); 130 } 131 }kx; 132 int main() 133 { 134 kx.work(); 135 return 0; 136 }
1 #include2 #include
1 #include2 #define ll long long 3 #define cri const register int 4 #define re register 5 #define pb push_back 6 #define fr first 7 #define sd second 8 #define mp make_pair 9 #define min(a,b) ((a)<(b)?(a):(b)) 10 #define max(a,b) ((a)>(b)?(a):(b)) 11 using namespace std; 12 const int inf=1e9+7; 13 int n,K,T; 14 int da[200010],mx[800010],mi[800010],w,ans,tmp_mx,tmp_mi; 15 vector< pair<int,int> >has[800010],tps[200010]; 16 bool can[800010],hav[800010]; 17 void ad1(cri k,cri l,cri r,cri L,cri R,const pair<int,int>x){ 18 if(l>=L&&r<=R){ 19 has[k].pb(x); 20 hav[k]=1; 21 return; 22 } 23 cri mid=l+r>>1; 24 if(L<=mid) ad1(k<<1,l,mid,L,R,x); 25 if(R>mid) ad1(k<<1|1,mid+1,r,L,R,x); 26 hav[k]=hav[k]||hav[k<<1]||hav[k<<1|1]; 27 } 28 inline void up(cri k){ 29 cri l=k<<1,r=k<<1|1; 30 can[k]=can[l]&&can[r]; 31 mx[k]=max(mx[l],mx[r]); 32 mi[k]=min(mi[l],mi[r]); 33 } 34 void ad2(cri k,cri l,cri r,cri x,cri y){ 35 if(l==r){ 36 da[l]++;can[k]=da[l]==1;w=da[l]>1; 37 tps[l].pb(mp(min(mi[k],y),max(mx[k],y))); 38 cri t=tps[l].size(); 39 mi[k]=tps[l][t-1].fr; 40 mx[k]=tps[l][t-1].sd; 41 return; 42 } 43 cri mid=l+r>>1; 44 if(x<=mid) ad2(k<<1,l,mid,x,y); 45 else ad2(k<<1|1,mid+1,r,x,y); 46 up(k); 47 } 48 void del(cri k,cri l,cri r,cri x){ 49 if(l==r){ 50 da[l]--;can[k]=da[l]==1;w=da[l]>1; 51 tps[l].pop_back(); 52 cri t=tps[l].size(); 53 if(!t) mx[k]=-inf,mi[k]=inf; 54 else mi[k]=tps[l][t-1].fr,mi[k]=tps[l][t-1].sd; 55 return; 56 } 57 cri mid=l+r>>1; 58 if(x<=mid) del(k<<1,l,mid,x); 59 else del(k<<1|1,mid+1,r,x); 60 up(k); 61 } 62 void query(cri k,cri l,cri r,cri x){ 63 if(l==r&&l==x) return; 64 if(mx[k] tmp_mi) return; 65 if(r<x){ 66 tmp_mx=max(tmp_mx,mx[k]); 67 return; 68 } 69 if(l>x){ 70 tmp_mi=min(tmp_mi,mi[k]); 71 return; 72 } 73 cri mid=l+r>>1; 74 query(k<<1,l,mid,x); 75 query(k<<1|1,mid+1,r,x); 76 } 77 void all(cri k,cri l,cri r){//cout< 78 if(!hav[k]){ 79 if(can[1]) ans+=r-l+1; 80 return; 81 } 82 cri t=has[k].size(); 83 for(int i=0;i 84 const pair<int,int>tmp=has[k][i]; 85 tmp_mx=-inf;tmp_mi=inf; 86 query(1,1,K,tmp.fr); 87 if(tmp_mx>tmp.sd||tmp_mi<tmp.sd){ 88 for(int j=i-1;j>=0;j--) del(1,1,K,has[k][j].fr);//,cout<<" del "<){ 89 return; 90 } 91 ad2(1,1,K,tmp.fr,tmp.sd);//cout<<" in "< 92 if(w){ 93 for(int j=i;j>=0;j--) del(1,1,K,has[k][j].fr);//,cout<<" del "< 94 return; 95 } 96 } 97 if(l==r){ 98 if(can[1]) ans++;//,cout< 99 for(int i=0;i ,1,K,has[k][i].fr);//,cout<<" del "<1 100 return; 101 } 102 cri mid=l+r>>1; 103 all(k<<1,l,mid); all(k<<1|1,mid+1,r); 104 for(int i=0;i ,1,K,has[k][i].fr);//,cout<<" del "<1 105 } 106 inline int read(re int a=0,re int b=1,re char ch=getchar()){ 107 while(ch<'0'||ch>'9') b=ch=='-'?-1:1,ch=getchar(); 108 while(ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48),ch=getchar(); 109 return a*b; 110 } 111 int main(){//freopen("r.out","r",stdin); 112 //freopen("w.out","w",stdout); 113 n=read(),K=read(),T=read(); 114 memset(mi,0x3f,sizeof mi); 115 for(int i=1;i<=T;i++){ 116 cri l=read(),r=read(),x=read();//cout< 117 ad1(1,1,n,l,r,mp(x,i)); 118 } 119 all(1,1,n); 120 printf("%d\n",ans); 121 return 0; 122 }
T2 大神题,考试想到了求出n!中求出5的个数,但想歪了,误认为只有后k位对答案有贡献,实际上5的个数是不同的。