测试40
Posted seamtn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测试40相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h> #define F(i,a,b) for(rg int i=a;i<=b;++i) #define LL long long #define il inline #define rg register #define pf(a) printf("%d ",a) #define phn puts("") using namespace std; int read(); #define N 200010 int n,lmt; int a[N],b[N],c[N<<1]; il int max(int x,int y)return x>y?x:y; struct tree int w,g,l,r; s[N<<2]; #define sx s[x] void biu(int x,int l,int r) sx.l=l;sx.r=r;sx.w=sx.g=0; if(l==r)return ; int mid=l+r>>1; biu(x<<1,l,mid);biu(x<<1|1,mid+1,r); #define lc s[x<<1] #define rc s[x<<1|1] il void down(int x) lc.w+=sx.g;lc.g+=sx.g; rc.w+=sx.g;rc.g+=sx.g; sx.g=0; void upd(int x,int p,int val) if(sx.l==sx.r) sx.w=max(val,sx.w); return ; if(sx.g)down(x); int mid=sx.l+sx.r>>1; if(p<=mid)upd(x<<1,p,val); else upd(x<<1|1,p,val); sx.w=max(lc.w,rc.w); void add(int x,int l,int r) if(l<=sx.l&&sx.r<=r) sx.w++;sx.g++; return ; if(sx.g)down(x); int mid=sx.l+sx.r>>1; if(l<=mid)add(x<<1,l,r); if(r>mid)add(x<<1|1,l,r); sx.w=max(lc.w,rc.w); int ask(int x,int l,int r) if(l<=sx.l&&sx.r<=r) return sx.w; if(sx.g)down(x); int mid=sx.l+sx.r>>1,ans=0; if(l<=mid)ans=max(ans,ask(x<<1,l,r)); if(r>mid)ans=max(ans,ask(x<<1|1,l,r)); return ans; int main() // freopen("ex_leader2.in","r",stdin); n=read(); F(i,1,n)a[i]=read(),b[i]=read(),c[i]=a[i],c[i+n]=b[i]; sort(c+1,c+n*2+1); lmt=unique(c+1,c+n*2+1)-c-1; biu(1,1,lmt); int x=0,ans=0; F(i,1,n) a[i]=lower_bound(c+1,c+lmt+1,a[i])-c; b[i]=lower_bound(c+1,c+lmt+1,b[i])-c; x=ask(1,b[i]+1,lmt)+1; ans=max(ans,x); if(b[i]>=a[i]) upd(1,a[i],x); else x=ask(1,a[i],lmt)+1; upd(1,a[i],x); add(1,b[i]+1,a[i]-1); printf("%d\n",ans); il int read() int s=0;char ch; while(ch=getchar(),!isdigit(ch)); for(;isdigit(ch);s=s*10+(ch^48),ch=getchar()); return s; /* g++ 1.cpp -g ./a.out 5 2 5 3 3 7 2 8 3 4 5 */
#include<bits/stdc++.h> #define F(i,a,b) for(rg int i=a;i<=b;++i) #define LL long long #define il inline #define rg register #define pf(a) printf("%d ",a) #define phn puts("") using namespace std; int read(); int n,m; #define N 200010 int c[N],to[N<<1],fir[N<<1],head[N],cnt; il void lian(int x,int y) to[++cnt]=y;fir[cnt]=head[x];head[x]=cnt; vector<pair<int,int> >que[N]; #define fst first #define scd second int T[N],ans[N],w[N],sta[N],top,vis[N]; int son[N],sz[N],dep[N],mxd; void gets(int x,int d) sz[x]=1;dep[x]=d;mxd=max(mxd,d); for(int i=head[x];i;i=fir[i]) int v=to[i]; gets(v,d+1); sz[x]+=sz[v]; if(sz[son[x]]<sz[v])son[x]=v; il void jia(rg int x,int p) for(;x<=mxd;x+=x&-x)w[x]+=p; il int ask(rg int x)int s=0;for(;x;x-=x&-x)s+=w[x];return s; void sear(int x) if(T[c[x]]==-1||T[c[x]]>dep[x]) if(T[c[x]]!=-1)jia(T[c[x]],-1); else sta[++top]=c[x]; T[c[x]]=dep[x];jia(dep[x],1); for(int i=head[x];i;i=fir[i])sear(to[i]); void dfs(int x) int v; for(int i=head[x];i;i=fir[i]) v=to[i]; if(v!=son[x])dfs(v); while(top)jia(T[sta[top]],-1),T[sta[top]]=-1,--top; if(son[x])dfs(son[x]); if(T[c[x]]!=-1)jia(T[c[x]],-1); else sta[++top]=c[x]; T[c[x]]=dep[x];jia(dep[x],1); for(int i=head[x];i;i=fir[i])if(to[i]!=son[x])sear(to[i]); int ed=que[x].size()-1; F(i,0,ed) ans[que[x][i].scd]=ask(min(dep[x]+que[x][i].fst,mxd)); int main() // freopen("xb.in","r",stdin); freopen("2.out","w",stdout); memset(T,-1,sizeof(T)); n=read();m=read();F(i,1,n)c[i]=read(); int x,d; F(i,2,n) x=read();lian(x,i); F(i,1,m)x=read(),d=read(),que[x].push_back(make_pair(d,i)); gets(1,1); mxd+=5; dfs(1); F(i,1,m)printf("%d\n",ans[i]); il int read() int s=0;char ch; while(ch=getchar(),!isdigit(ch)); for(;isdigit(ch);s=s*10+(ch^48),ch=getchar()); return s; /* g++ 2.cpp -g ./a.out 7 3 2 2 1 2 1 1 1 1 1 2 2 3 3 4 41 4 24 5 2 g++ 2.cpp -g time ./a.out 5 5 1 3 3 2 2 1 1 3 3 1 0 1 3 1 2 2 1 3 2 */
#include<bits/stdc++.h> #define F(i,a,b) for(rg int i=a;i<=b;++i) #define LL long long #define il inline #define rg register #define pf(a) printf("%d ",a) #define phn puts("") using namespace std; #define int LL int read(); char s[3005]; int n,len; int las[3005],head[30],f[3005][3005]; const int mod=998244353; signed main() scanf("%s",s+1); n=strlen(s+1); len=read(); F(i,1,n)las[i]=head[s[i]-‘a‘],head[s[i]-‘a‘]=i; f[0][0]=1; F(i,1,n) f[i][0]=1; F(j,1,len) f[i][j]=(las[i]?(f[i-1][j]+f[i-1][j-1]-f[las[i]-1][j-1]): (f[i-1][j]+f[i-1][j-1]))%mod; printf("%lld\n",(f[n][len]+mod)%mod); il int read() int s=0;char ch; while(ch=getchar(),!isdigit(ch)); for(;isdigit(ch);s=s*10+(ch^48),ch=getchar()); return s; /* g++ 3.cpp -g ./a.out ppsdvnvwnczwptuqbfwo 9 */
T0:
0、这次考试要交文件,
然鹅。。。
交文件要写freopen()!!!!!
提交文件: 1、要打freopen2、三个文件夹,文件名
还好不是正规考试。。。。。。
1、一上来看T1题目描述是水题,去刚T1。但是T3是相对最简单的的。
T1看出是数据结构维护DP,但是打了个树状数组发现DP想错了,一直在推DP,非常混乱。
耗费了一个半小时,弃了写T2。T2暴力比较好写。
回去看T1,推DP,写个没有数据结构的DP,终于对了。再把线段树加上去,终于A了。
2、部分分没拿满。这两次考试都是。
最后剩下时间应该先去拿满部分分,再去尝试打正解。
读题的时候要看一眼部分分有哪些。
3、正确开题顺序:T3,T1,T2。
T1:
DP。
设f[i][j] 表示处理完 i个水晶,已经选择的水晶中最小的为j 的最大摧毁个数。
讨论ai与bi大小关系,瞎**转移
经验:
1、数据结构维护DP要先把DP写出来,看对不对,再去打数据结构,
2、维护东西多了以后不能用树状数组,只能线段树。例如同时单点更新最大值和区间加。
总结:
DP功底不熟。而且比较盲目,应该先写出dp看对不对。
T2:
非正解可以离线用启发式水过去。
树上启发式+树状数组。启发式维护这个颜色离当前点最近的deep。(含义上本应那样,但这里维护全局deep,否则不好维护,不能共用)
树状数组deep为下标维护个数。
部分分可以线段树合并或者dfs序+莫队
T3:
对T3有畏难心理。但有时T3最简单。
1、noip不会有后缀数组。
2、没有打10分的部分分。但是就是个特判。下次要注意读题时候想部分分。
3、合法序列方案数考虑DP
4、DP功底不太够,没有看出规律。
5、主要T1时间占用太多,T3没时间了。
暴力比较好想,dfs枚举+hash或trie。枚举是组合数复杂度。
根据数据范围,复杂度一看就应该是S^2
设f[i][j] 表示处理完串 的前i 个位置,?度为 j的本质不同的子序列个数。
转移考虑添加一个尾部字符,直接想法f[i][j]=f[i-1][j]+f[i][j-1]
然而这样我们会算重,考虑把算重的部分减掉。
算重的部分一定是以a[i] 为结尾的串。
所以设 a[i]上一次出现的位置为 p,那么以p 结尾的串与算重的串一一对应。
以p结尾,转移到j长度的个数是f[p-1][j-1]
预处理出每个点的las ,转移方程式:f[i][j]=f[i-1][j]+f[i][j-1]-f[p-1][j-1]
对于第一次出现的a[i]特殊考虑,不必减重。
。
以上是关于测试40的主要内容,如果未能解决你的问题,请参考以下文章