zoukankan      html  css  js  c++  java
  • noip模拟赛

    我 是 个 傻 逼

    T1

    给你一个长度不超过10的数字串,问你可不可以加若干加号和一个等号使它变成一个等式

    sol:

    T2

    给一个01串,每个地方有一个代价$c_i$,交换两个字符的代价是$c_i + c_j$

    求最后逆序对数 - 交换代价的最大值

    $n leq 1000$

    sol:

    首先想到,交换两个位置$(i,j)$ $(j > i)$对答案的贡献其实是$j - i - c_i - c_j$

    于是我们可以想到一个贪心,每次从后往前找$1$,每找到一个$1$就从前往后找一个最优的$0$,然后交换

    这样可以贪到80分

    然后去问了管老师,管老师:多贪几次

    我:.... %%%

    正解其实是dp

    每一个位置最多只会交换一次

    我们可以记$f(i,j,k)$表示前$i$位已经确定,有$j$个位置从$1$变成了$0$,$k$个位置从$0$变成了$1$

    转移的时候我们枚举$i + 1$是$0$还是$1$即可

    发现并不需要记$j,k$具体值,只需要记$j-k$

    于是就做完了

    T3

    一棵树,每个点上有一个灯,灯有开关,一开始全关着,树上有m个人,每个人有初始位置

    你要维护:

    1.让编号在$[l,r]$的人走到$x$点

    2.让编号在$[l,r]$的人向根走$x$步,走到根就不走了

    3.让编号为$x$的人按一下开关,并询问$x$子树里所有开灯的点到$x$的距离之和

    sol:

    分为两部分来做

    1.维护每个人的位置,显然是一个线段树区间赋值 & 区间加

    注意当区间赋值的时候要顺便把这个点的加法标记清除掉

    2.按开关,询问子树开灯的点到这个点的距离和

    我们可以按dfs序开两个树状数组表示子树权值和 & 子树内有多少个开灯的点

    然后模拟即可

    T2只贪了一次 = 80分

    T3fa[1]没有设为1 = GG

    于是180被爆踩

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #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 mp make_pair
    #define pb push_back
    #define xx first
    #define yy second
    typedef long long ll;
    typedef pair<int,int> pii;
    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;
    }
    const int maxn=10;
    char s[maxn];
    int n;
    int solve() {
        scanf("%s",s+1);
        n=strlen(s+1);
        rep(x,1,n-1) {
            rep(S,0,(1<<n-1)-1) {
                int left=0,cur=0,right=0;
                rep(i,1,x) {
                    cur=cur*10+s[i]-'0';
                    if(S>>i-1&1) left+=cur,cur=0;
                }
                left+=cur;cur=0;
                rep(i,x+1,n) {
                    cur=cur*10+s[i]-'0';
                    if(S>>i-1&1) right+=cur,cur=0;
                }
                right+=cur;cur=0;
                if(left==right) return 1;
            
            }
        }
        return 0;
    }
    int main() {
        freopen("equation.in","r",stdin);
        freopen("equation.out","w",stdout);
        int T=read();
        while(T--) puts(solve()?"Yes":"No");
        return 0;
    }
    T1
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #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 mp make_pair
    #define pb push_back
    #define xx first
    #define yy second
    typedef long long ll;
    typedef pair<int,int> pii;
    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;
    }
    const int maxn=2610;
    const int inf=1e9;
    int n,A[maxn];
    int f[2][maxn*2];// (0 -> 1) - (1 -> 0)
    char p[maxn];
    int main() {
        freopen("inverse.in","r",stdin);
        freopen("inverse.out","w",stdout);
        n=read();
        scanf("%s",p+1);
        rep(i,1,n) A[i]=read();
        rep(i,0,2*n) f[0][i]=-inf;
        f[0][n]=0;int cur=0,c1=0;
        rep(i,1,n) {
            cur^=1;
            rep(j,0,2*n) f[cur][j]=-inf;
            rep(j,0,2*n) {
                int& ans=f[cur^1][j];if(ans==-inf) continue;
                if(p[i]=='1') {
                    f[cur][j]=max(f[cur][j],ans);
                    f[cur][j-1]=max(f[cur][j-1],ans-A[i]+c1+j-n);
                }
                else {
                    f[cur][j]=max(f[cur][j],ans+c1+j-n);
                    f[cur][j+1]=max(f[cur][j+1],ans-A[i]);
                }
            }
            if(p[i]=='1') c1++;
        }
        printf("%d
    ",f[cur][n]);
        return 0;
    }
    T2
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #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--)
    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 maxn=160010;
    int n,m,first[maxn],nxt[maxn<<1],to[maxn<<1],e;
    void AddEdge(int u,int v) {
        to[++e]=v;nxt[e]=first[u];first[u]=e;
        to[++e]=u;nxt[e]=first[v];first[v]=e;
    }
    int anc[maxn][20],dep[maxn],st[maxn],en[maxn],cnt;
    void dfs(int x) {
        st[x]=++cnt;dep[x]=dep[anc[x][0]]+1;
        rep(i,1,19) anc[x][i]=anc[anc[x][i-1]][i-1];
        for(int i=first[x];i;i=nxt[i]) if(to[i]!=anc[x][0]) {
            anc[to[i]][0]=x;dfs(to[i]);
        }
        en[x]=cnt;
    }
    int swim(int x,int k) {
        k=min(k,dep[x]-1);
        dwn(i,19,0) if(k>>i&1) x=anc[x][i];
        return x;
    }
    int addv[maxn<<2],setv[maxn<<2],p[maxn],A[maxn];
    void build(int o,int l,int r) {
        if(l==r) setv[o]=p[l];
        else {
            int mid=l+r>>1,lc=o<<1,rc=lc|1;
            build(lc,l,mid);build(rc,mid+1,r);
        }
    }
    void pushdown(int o) {
        int lc=o<<1,rc=lc|1;
        if(setv[o]) {
            addv[lc]=addv[rc]=0;
            setv[lc]=setv[rc]=setv[o];
            setv[o]=0;
        }
        if(addv[o]) {
            addv[lc]+=addv[o];
            addv[rc]+=addv[o];
            addv[o]=0;
        }
    }
    void update(int o,int l,int r,int ql,int qr,int t,int v) {//t=1 -> set, t=2 -> add
        if(ql<=l&&r<=qr) {
            if(t==1) addv[o]=0,setv[o]=v;
            else addv[o]+=v; 
        }
        else {
            pushdown(o);
            int mid=l+r>>1,lc=o<<1,rc=lc|1;
            if(ql<=mid) update(lc,l,mid,ql,qr,t,v);
            if(qr>mid) update(rc,mid+1,r,ql,qr,t,v);
        }
    }
    int query(int o,int l,int r,int p) {
        if(l==r) return swim(setv[o],addv[o]);
        pushdown(o);
        int mid=l+r>>1,lc=o<<1,rc=lc|1;
        if(p<=mid) return query(lc,l,mid,p);
        return query(rc,mid+1,r,p);
    }
    struct Fenwich {
        ll sumv[maxn];
        Fenwich() {memset(sumv,0,sizeof(sumv));}
        void add(int x,int v) {for(;x<=n;x+=x&-x) sumv[x]+=v;}
        ll sum(int x) {ll res=0;for(;x;x-=x&-x) res+=sumv[x];return res;}
    }T1,T2;
    int main() {
        freopen("robot.in","r",stdin);
        freopen("robot.out","w",stdout);
        n=read();m=read();
        rep(i,2,n) AddEdge(read(),read());
        rep(i,1,m) p[i]=read();
        dfs(1);build(1,1,m);
        dwn(i,read(),1) {
            int t=read();
            if(t==1||t==2) {
                int l=read(),r=read(),x=read();
                update(1,1,m,l,r,t,x);
            }
            else {
                int k=read(),x=query(1,1,m,k),v=(A[x]?-1:1);
                printf("%lld
    ",T2.sum(en[x])-T2.sum(st[x]-1)-(ll)dep[x]*(T1.sum(en[x])-T1.sum(st[x]-1)));
                T1.add(st[x],v);T2.add(st[x],v*dep[x]);
                A[x]^=1;
            }
        }
        return 0;
    }
    T3
  • 相关阅读:
    codevs2894、2837、1669、2503、3231
    poj2528
    HDU 1542 Atlantis(矩形面积并)
    Light OJ 1080
    陶哲轩实分析 2.2节 习题试解
    Linux多线程实践(六)使用Posix条件变量解决生产者消费者问题
    css3模糊图片
    高速掌握Lua 5.3 —— I/O库 (1)
    覆盖率測试工具gcov的前端工具_LCOV_简单介绍
    MySQL显示状态信息
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9792816.html
Copyright © 2011-2022 走看看