• 11.2NOIP模拟赛


    /*
    根右左遍历后最长上升子序列
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    inline LL read()
    {
        char c=getchar();LL num=0,f=1;
        for(;!isdigit(c);c=getchar())
            f=c=='-'?-1:f;
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num*f;
    }
    
    const int N=1e5+5;
    
    int n;
    LL w[N];
    int son[N][2];
    
    LL dfn[N],tim;
    void dfs(int u)
    {
        dfn[++tim]=w[u];
        if(son[u][1]!=0)
            dfs(son[u][1]);
        if(son[u][0]!=0)
            dfs(son[u][0]);
    }
    
    LL lis[N],len;
    int main()
    {
        freopen("point.in","r",stdin);
        freopen("point.out","w",stdout);
         int size = 256 << 20; // 256MB  
            char *p = (char*)malloc(size) + size;  
            __asm__("movl %0, %%esp
    " :: "r"(p));
     
        n=read();
        for(int i=1;i<=n;++i)
            w[i]=read();
        for(int i=1;i<=n;++i)
            son[i][0]=read(),son[i][1]=read();
        dfs(1);
        lis[len=1]=dfn[1];
        for(int i=2;i<=tim;++i)
        {
            if(dfn[i]>lis[len]) lis[++len]=dfn[i];
            else lis[lower_bound(lis+1,lis+len+1,dfn[i])-lis]=dfn[i];
        }
        cout<<len;
        fclose(stdin);fclose(stdout);
        return 0;
    }

    /*
    序列分为移动的序列和未移动的序列两部分
    询问离散化后 
    对于移动的序列,抽出来树状数组统计逆序对
    对于未移动的序列,想办法能直接统计答案
    首先维护哪些数未被移动过,然后对于未被移动过的数求前缀和sum[i] 
    这样就得到了1~i中未被移动过的数的个数,进而能O(1)得出每段区间未被移动的数的个数。
    考虑一个移动了的元素,从i向前移动到了j,那么他对答案的贡献,就是sum[j,i]
    因为向前移动后[j,i]这段区间所有数都比他小。
    同理一个元素从i向后移动到了j,那么他对答案的贡献为sum[i,j]
    所以未被移动的元素对答案的贡献和就是Σabs(sum[原来位置]-sum[移动后的位置]) 
    */
    #include<bits/stdc++.h>
    
    #define N 200007
    #define ll long long
    
    using namespace std;
    int n,m,cnt,num;
    ll ans;
    ll pos[N],a[N],sum[N];
    struct node{
        int L,R;
    }ask[N];
    
    struct BIT_{
        
        int n;ll a[N];
        
        static int lowbit(int x){
            
            return x & -x;
        }
        
        void clear(){
            
            for(int i=1;i<=n;i++) a[i]=0;
        }
        
        ll query(int pos){
            
            ll ans=0;
            for(int i=pos;i>0;i-=lowbit(i)) ans+=a[i];
            return ans;
        }
        
        void update(int pos,int val){
            
            for(int i=pos;i<=n;i+=lowbit(i)) a[i]+=val;
        }
    }bit;
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    void discrete()
    {
        for(int i=1;i<=n;i++)
        {
            ask[i].L=read();ask[i].R=read();
            a[i]=ask[i].L;a[i+n]=ask[i].R;
            pos[i]=i;pos[i+n]=i+n;
        }
        sort(a+1,a+n*2+1);
        num=unique(a+1,a+n*2+1)-a-1;
        for(int i=1;i<=num;i++) sum[i]=sum[i-1]+a[i]-a[i-1]-1;
        for(int i=1;i<=n;i++)
        {
            ask[i].L=lower_bound(a+1,a+num+1,ask[i].L)-a;
            ask[i].R=lower_bound(a+1,a+num+1,ask[i].R)-a;
            swap(pos[ask[i].L],pos[ask[i].R]);
        }
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        n=read();discrete();
        bit.n=n<<1; bit.clear();
        for(int i=num;i>=1;i--)
        {
            ans+=bit.query(pos[i]);
            ans+=abs(sum[pos[i]]-sum[i]);
            bit.update(pos[i],1);
        }
        cout<<ans<<endl;
        return 0;
    }

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    
    #define N 200007
    
    using namespace std;
    int n,m,ans,cnt;
    int head[N],pos[N],vis[N];
    struct edge{
        int u,v,nxt;
    }e[N<<1];
    struct node{
        int col,x,cur;
    };queue<node>q;
    inline void add(int u,int v)
    {
        e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
    }
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    void bfs_change(int cur,int change)
    {
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof vis);
        node u;u.col=pos[1];u.x=1;vis[1]=1;
        q.push(u);
        while(!q.empty())
        {
            u=q.front();q.pop();
            if(u.col==cur) pos[u.x]=change;
            for(int i=head[u.x];i;i=e[i].nxt)
            {
                int v=e[i].v;
                if(vis[v]) continue;
                vis[v]=1;
                node tmp;tmp.x=v;tmp.col=pos[v];q.push(tmp);
            }
        }
    }
    
    void bfs_calc()
    {
        ans=1;
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof vis);
        node u;u.col=pos[1];u.x=1;u.cur=pos[1];
        vis[1]=1;q.push(u);
        while(!q.empty())
        {
            u=q.front();q.pop();
            if(u.col!=u.cur) ans++;
            for(int i=head[u.x];i;i=e[i].nxt)
            {
                int v=e[i].v;
                if(vis[v]) continue;
                vis[v]=1;node tmp;
                tmp.x=v;tmp.col=pos[v];tmp.cur=pos[u.x];q.push(tmp);
            }
        }
    }
    
    int main()
    {
        freopen("simulator.in","r",stdin);
        freopen("simulator.out","w",stdout);
        int x,y;
        n=read();m=read();
        for(int i=1;i<=n;i++) pos[i]=read();
        for(int i=1;i<n;i++)
        {
            x=read();y=read();
            add(x,y);add(y,x);
        }
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();
            bfs_change(x,y);
            bfs_calc();
            printf("%d
    ",ans);
        }
        return 0;
    }
    30暴力
    /*
    bzoj1483 放到树上
    见https://www.cnblogs.com/L-Memory/p/9898249.html 
    同理 vector+启发式合并。 
    */
    #include<bits/stdc++.h>
    
    #define ll long long
    #define M 200010
    using namespace std;
    int read()
    {
        int nm = 0, f = 1;
        char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
        return nm * f;
    }
    
    int note[M], sz[M], cor[M], id[M];
    vector<int>to[M], to1[M];
    int n, q, ans;
    void dfs(int now, int fa)
    {
        if(cor[now] != 0 && cor[now] != cor[fa]) ans++;
        for(int i = 0; i < to[now].size(); i++)
        {
            int vj = to[now][i];
            if(vj == fa) continue;
            dfs(vj, now);
        }
    }
    
    void del(int x)
    {
        for(int i = 0; i < to[x].size(); i++)
        {
            int vj = to[x][i];
            if(cor[vj] != cor[x]) ans--;
        }
    }
    void insert(int x)
    {
        for(int i = 0; i < to[x].size(); i++)
        {
            int vj = to[x][i];
            if(cor[vj] != cor[x]) ans++;
        }
    }
    int tot = 0, tot2 = 0;
    int main()
    {
        freopen("simulator.in", "r", stdin);
        freopen("simulator.out", "w", stdout);
        n = read(), q = read();
        for(int i = 1; i <= n; i++) cor[i] = read(), sz[cor[i]]++, to1[cor[i]].push_back(i), id[i] = i, note[i] = i;
        for(int i = 1; i < n; i++)
        {
            int vi = read(), vj = read();
            to[vi].push_back(vj), to[vj].push_back(vi);
        }
        to[1].push_back(0), cor[0] = 0x3e3e3e3e;
        dfs(1, 0);
        while(q--)
        {
            int x = read(), y = read();
            int xn = id[x], yn = id[y];
            if(sz[xn] < sz[yn])
            {
                tot += sz[xn], tot2 += to1[xn].size();
                for(int i = 0; i < to1[xn].size(); i++)
                {
                    int op = to1[xn][i];
                    del(op);
                    to1[yn].push_back(op);
                }
                for(int i = 0; i < to1[xn].size(); i++)
                {
                    int op = to1[xn][i];
                    cor[op] = yn;
                }
                for(int i = 0; i < to1[xn].size(); i++)
                {
                    int op = to1[xn][i];
                    insert(op);
                }
                to1[xn].clear();
                sz[yn] += sz[xn];
                sz[xn] = 0;
                id[x] = 0;
            }
            else
            {
                tot+=sz[yn], tot2 += to1[yn].size();
                for(int i = 0; i < to1[yn].size(); i++)
                {
                    int op = to1[yn][i];
                    del(op);
                    to1[xn].push_back(op);
                }
                for(int i = 0; i < to1[yn].size(); i++)
                {
                    int op = to1[yn][i];
                    cor[op] = xn;
                }
                for(int i = 0; i < to1[yn].size(); i++)
                {
                    int op = to1[yn][i];
                    insert(op);
                }
                to1[yn].clear();
                sz[xn] += sz[yn];
                sz[yn] = 0;
                id[y] = xn;
                id[x] = 0;
            }
            cout << ans << "
    ";
        }
        return 0;
    }
  • 相关阅读:
    找到关注点
    c中printf必须在所有的变量申明之后才能用?
    在eclipse里面运行项目,并未出现中文乱码的问题;但是打成war包运行, tomcat运行startup.bat后控制台中文乱码
    《分工与贸易》笔记
    《范围:为什么通才能在专业化的世界中取胜》笔记
    《不充分均衡》笔记
    ”苦“没有价值
    《为什么佛学是真的》笔记
    《强力瞬间》笔记
    你和你的渴望
  • 原文地址:https://www.cnblogs.com/L-Memory/p/9898342.html
Copyright © 2020-2023  润新知