• BestCoder Round #73


    这场比赛打完后可以找何神玩了orz(orz)*

    T1Rikka with Chess

    嘿嘿嘿。输出n/2+m/2即可。

    我能说我智商捉鸡想了4min吗?

    T2Rikka with Graph

    由于N个点的连通块最少有N-1条边,所以至多删两条。

    暴力枚举然后并查集判判即可。

    T3Rikka with Array

    奥妙重重的数位dp。

    设f[i][j][d1][d2][d3]表示前i位,x1与x2的数位差为j。大小关系如下:

    d1=0 x1<x2
    d1=1 x1=x2
    d1=2 x1>x2
    d2=0 x1<=n
    d2=1 x1>n
    d3=0 x2<=n
    d3=1 x2>n

    然后滚动数组DP一下。

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    typedef long long ll;
    const int mod=998244353;
    const int maxn=1010;
    struct bign {
        int s[maxn],len;
        bign operator = (const char* a) {
            memset(s,0,sizeof(s));len=strlen(a);
            rep(i,0,len-1) s[i]=a[len-i-1]-'0';
        }
        void operator /= (int b) {
            int x=0;
            dwn(i,len-1,0) {
                int v=s[i]+x;
                s[i]=v/2;
                x=(v%2)*10;
            }
            while(!s[len-1]&&len>1) len--;
        }
        void print() {
            dwn(i,len-1,0) printf("%d",s[i]);
            puts("");
        }
    }N;
    char s[maxn];
    int bit[maxn];
    ll f[2][maxn*2][3][2][2];
    void solve() {
        scanf("%s",s);N=s;int n=0;
        while(N.s[0]||N.len!=1) bit[++n]=N.s[0]&1,N/=2;
        memset(f,0,sizeof(f));
        int cur=0;f[0][n][1][0][0]=1;
        rep(i,0,n-1) {
            cur^=1;memset(f[cur],0,sizeof(f[cur]));
            rep(j,-i+n,i+n) rep(d1,0,2) rep(d2,0,1) rep(d3,0,1) {
                ll& ans=f[cur^1][j][d1][d2][d3];
                (f[cur][j][d1][bit[i+1]?0:d2][bit[i+1]?0:d3]+=ans)%=mod;
                (f[cur][j][d1][(!bit[i+1])?1:d2][(!bit[i+1])?1:d3]+=ans)%=mod;
                (f[cur][j+1][2][(!bit[i+1])?1:d2][bit[i+1]?0:d3]+=ans)%=mod;
                (f[cur][j-1][0][bit[i+1]?0:d2][(!bit[i+1])?1:d3]+=ans)%=mod;
            }
        }
        ll ans=0;
        rep(i,n+1,2*n) (ans+=f[cur][i][0][0][0])%=mod;
        printf("%lld
    ",ans);
    }
    int main() {
        int T=read();
        while(T--) solve();
        return 0;
    }
    View Code

    T4:Rikka with Sequence

    我选择go die。

    T5:Rikka with Phi

    考虑用线段树来做。

    对于操作1,暴力变换带标记且不全为1的区间。

    对于操作2,在线段树上打标记。

    对于操作3,线段树上直接查询。

    等等,我们写程序要讲道理对不对。

    我们发现对于一个[1,10^7]的数x,最多执行logx次操作1x就变成了1。

    我们可以进行势能分析,初始势能为nlogx。

    对于操作1,每变换一次势能-1。

    对于操作2,至多增加log^2n的势能。

    对于操作3,时间复杂度恒定O(logn)

    所以总时间复杂度O(nlog^2n)

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar() {
        if(head==tail) {
            int l=fread(buffer,1,BufferSize,stdin);
            tail=(head=buffer)+l;
        }
        return *head++;
    }
    inline int read() {
        int x=0,f=1;char c=Getchar();
        for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
        return x*f;
    }
    typedef long long ll;
    const int N=10000010;
    const int maxn=300010;
    int vis[N],phi[N],pri[N/10],cnt;
    void gen(int n) {
        phi[1]=1;
        rep(i,2,n) {
            if(!vis[i]) pri[++cnt]=i,phi[i]=i-1;
            rep(j,1,cnt) {
                if(i*pri[j]>n) break;
                vis[i*pri[j]]=1;
                if(i%pri[j]==0) {phi[i*pri[j]]=phi[i]*pri[j];break;}
                phi[i*pri[j]]=phi[i]*(pri[j]-1);
            }
        }
    }
    ll sumv[maxn*4],is[maxn*4],setv[maxn*4];
    void pushdown(int o,int l,int r) {
        if(setv[o]) {
            int lc=o<<1,rc=lc|1,mid=l+r>>1;
            setv[lc]=setv[rc]=setv[o];
            is[lc]=is[rc]=1;
            sumv[lc]=setv[o]*(mid-l+1);
            sumv[rc]=setv[o]*(r-mid);
            setv[o]=0;
        }
    }
    void maintain(int o,int l,int r) {
        int lc=o<<1,rc=lc|1;
        if(setv[o]) sumv[o]=(r-l+1)*setv[o],is[o]=(setv[o]!=1);
        else sumv[o]=sumv[lc]+sumv[rc],is[o]=is[lc]|is[rc];
    }
    void update(int o,int l,int r,int ql,int qr,int v) {
        if(ql<=l&&r<=qr) setv[o]=v;
        else {
            pushdown(o,l,r);
            int lc=o<<1,rc=lc|1,mid=l+r>>1;
            if(ql<=mid) update(lc,l,mid,ql,qr,v);
            if(qr>mid) update(rc,mid+1,r,ql,qr,v);
        }
        maintain(o,l,r);
    }
    void update2(int o,int l,int r,int ql,int qr) {
        if(ql<=l&&r<=qr&&setv[o]) setv[o]=phi[setv[o]];
        else {
            pushdown(o,l,r);
            int lc=o<<1,rc=lc|1,mid=l+r>>1;
            if(ql<=mid&&is[lc]) update2(lc,l,mid,ql,qr);
            if(qr>mid&&is[rc]) update2(rc,mid+1,r,ql,qr);
        }
        maintain(o,l,r);
    }
    void build(int o,int l,int r) {
        sumv[o]=is[o]=setv[o]=0;
        if(l==r) setv[o]=read();
        else {
            int lc=o<<1,rc=lc|1,mid=l+r>>1;
            build(lc,l,mid);build(rc,mid+1,r);
        }
        maintain(o,l,r);
    }
    ll query(int o,int l,int r,int ql,int qr) {
        if(ql<=l&&r<=qr) return sumv[o];
        pushdown(o,l,r);
        int lc=o<<1,rc=lc|1,mid=l+r>>1;ll ans=0;
        if(ql<=mid) ans+=query(lc,l,mid,ql,qr);
        if(qr>mid) ans+=query(rc,mid+1,r,ql,qr);
        return ans;
    }
    void solve() {
        int n=read(),m=read();
        build(1,1,n);
        while(m--) {
            int t=read(),l=read(),r=read();
            if(t==1) update2(1,1,n,l,r);
            else if(t==2) update(1,1,n,l,r,read());
            else printf("%lld
    ",query(1,1,n,l,r));
        }
    }
    int main() {
        gen(10000000);
        dwn(T,read(),1) solve();
        return 0;
    }
    View Code
  • 相关阅读:
    window.open全屏显示
    js关闭当前页面
    sublime text 3 3126注册码
    关闭tomcat8080端口
    给json数组添加新字段并赋值
    怎么把json数据alert
    js里url里有特殊字符(如&)情况,后台request.getParameter("url")里&变成&
    request.getParameter乱码
    javaMail 详解
    JavaMail使用SMTP协议发送电子邮件(详解)
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5211283.html
Copyright © 2020-2023  润新知