20191030

前言

  • 第一次交文件……
  • 先叙述一下我的没脸的行为:
  • T1我的freopen写错了。网站成绩一出后我发现我FE了。
  • 然后非常震惊的我飞快的改了freopen交到网站上去,AC了。
  • 我痛心疾首心想就当是一次教训吧。
  • 结果吃完饭回来公布考试成绩:我AC了!!
  • 好像是收卷收晚了我当时已经改了然后收上去是对的?heiheihei。
  • T2我还看错题了我修改的是原序列但是我也AC了(kx&skyh也看错了WA70)!!heiheihei。
  • 总之这是非常没脸的骗到了130分。

T1

  • 其实出题人太善良了,我认为这个题的N和T应该开到1e7的。
  • 我的方法是用$\Theta(NlogN)$的时间复杂度内预处理出所有答案然后$\Theta(T)$回答所有询问。
  • 设a[i]为满足$x^i>i!$的最小x,显然a[i]随i的增大单调不降。
  • 利用double存下倍数并用快速幂实现快速转移就行了。
  • 时间复杂度$\Theta(NlogN)$,空间复杂度$\Theta(N)$。
#include<cstdio>
int const lt=1e5;
double const o=1.0,eps=1e-9;
int n;
int a[lt|1];
double la;
inline double power(double x,int y){
    double as=1;
    for(;y;y>>=1,x=x*x)
        if(y&1)as=as*x;
    return as;
}
int main(){
    freopen("yuuutsu.in","r",stdin);
    freopen("yuuutsu.out","w",stdout);
    a[1]=2;
    la=2;
    for(register int i=2;i<=lt;++i){
        a[i]=a[i-1];
        la*=(double)a[i]/(double)i;
        while(la-o<eps)
            ++a[i],la*=power((double)a[i]/(double)(a[i]-1),i);
    }
    int T,x,y;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&x,&y);
        puts(x<a[y]?"Yes":"No");
    }
    return 0;
}
View Code

T2

  • 直接利用差分。改变序列中的一个位置差分数组中只会有两个位置发生改变。
  • 我们把%k相同的位置分为一组,那么每次修改后答案的变化只会取决于对应一组中的最后一个元素。
  • 然后就可以直接维护了。
  • 考试一眼秒切了,还给kx说这是傻逼题。
  • 结果在kx通过大样例1个小时后我才终于调过……
  • 时空复杂度$\Theta(N)$。
#include<cstdio>
#define ll long long
using namespace std;
inline int read(){
    int ss(0),pp(0);char bb(getchar());
    for(;bb<48||bb>57;bb=getchar())pp=bb=='-';
    while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
    return pp?-ss:ss;
}
int const N=3e6+5;
int n,q,k,lit;
int a[N],b[N],c[N];
int la,ct,ps[N];
int main(){
    freopen("august.in","r",stdin);
    freopen("august.out","w",stdout);
    n=read(),k=read(),q=read();
    lit=n-k+1;
    for(register int i=1;i<=n;++i)a[i]=read(),b[i]=a[i]-a[i-1];
    for(register int i=1;i<=lit;++i)c[i+k]=c[i]-b[i];
    for(register int i=lit+1;i<=n;++i)
        if(c[i]!=b[i])++ct;
    if(ct)puts("No");
    else la=1,puts("Yes");
    for(register int i=lit;i<=n;++i)ps[i%k]=i;
    for(register int i=1;i<=q;++i){
        int hh=read(),y=read();
        int x=ps[hh%k],z=c[x]==b[x];
        if(hh<=lit)c[x]-=y;
        b[hh]+=y;
        if(z && y)++ct,la=0;
        else if(!z && c[x]==b[x])la=!--ct;
        if(++x<=n){
            z=c[x]==b[x];
            if(hh+1<=lit)c[x]+=y;
            b[hh+1]-=y;
            if(z && y)++ct,la=0;
            else if(!z && c[x]==b[x])la=!--ct;
        }
        puts(la?"Yes":"No");
    }
    return 0;
}
View Code

T3

  • dsu on tree。维护方法类似permu,不再赘述。
  • 时间复杂度$\Theta(NlogN)$,空间复杂度$\Theta(N)$。
#include<cstdio>
#define ll long long
inline int read(){
    int ss(0);char bb(getchar());
    while(bb<48||bb>57)bb=getchar();
    while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
    return ss;
}
int const N=2e5+5;
int n;
int w[N],ps[N];
int head[N],Next[N],to[N],t;
int siz[N],son[N];
int l[N],r[N];
ll a[N],ans,tans;
inline void add(int x,int y){
    to[++t]=y;
    Next[t]=head[x],head[x]=t;
    return ;
}
int dfs(int x){
    for(int i=head[x],y,nw=0;i;i=Next[i]){
        siz[x]+=dfs(y=to[i]);
        if(siz[y]>nw)nw=siz[son[x]=y];
    }
    return ++siz[x];
}
inline void update(int x,ll y){
    tans+=y*(r[x]-l[x]+1)*(r[x]-l[x]+2)>>1;
    return ;
}
inline void Get(int x){
    l[x]=r[x]=x;
    int lx=x-1,rx=x+1;
    if(!l[lx]&&!r[rx]){++tans;return ;}
    if(l[lx]&&!r[rx])return update(lx,-1),update(r[l[x]=l[lx]]=x,1);
    if(!l[lx])return update(rx,-1),update(l[r[x]=r[rx]]=x,1);
    update(lx,-1),update(rx,-1);
    return update(l[r[l[lx]]=r[rx]]=l[lx],1);
}
void modify(int x){
    Get(ps[x]);
    for(int i=head[x];i;i=Next[i])modify(to[i]);
    return ;
}
void clear(int x){
    l[ps[x]]=r[ps[x]]=0;
    for(int i=head[x];i;i=Next[i])clear(to[i]);
    return ;
}
void dsu(int x){
    for(int i=head[x];i;i=Next[i])
        if(to[i]!=son[x])dsu(to[i]),clear(to[i]),tans=0;
    if(!son[x]){Get(ps[x]),ans+=(a[x]=tans)*w[x];return ;}
    dsu(son[x]),Get(ps[x]);
    ll z=0;
    for(int i=head[x];i;i=Next[i])
        if(to[i]!=son[x])modify(to[i]),z+=a[to[i]];
    a[x]=tans,ans+=(tans-z-a[son[x]])*w[x];
    return ;
}
int main(){
    freopen("sagittarius.in","r",stdin);
    freopen("sagittarius.out","w",stdout);
    n=read();
    for(register int i=2;i<=n;++i)add(read(),i);
    for(register int i=1;i<=n;++i)ps[read()]=i;
    for(register int i=1;i<=n;++i)w[i]=read();
    dfs(1),dsu(1);
    printf("%lld",ans);
    return 0;
}
View Code
posted @ 2019-10-31 14:59  remarkable  阅读(296)  评论(13编辑  收藏  举报