测试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
*/
View Code
#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
*/
View Code
#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

*/
View Code

 

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]特殊考虑,不必减重。

posted @ 2019-09-08 17:34  seamtn  阅读(140)  评论(0编辑  收藏  举报