zoukankan      html  css  js  c++  java
  • YNOI2016 这是我自己的发明

    看到这个标题立刻想到:、

    “绝地科学家,八倍不屏息啊,八百里外把头打啊...”

    首先我们发现如果只考虑第二个操作,这棵树就是假的,我们可以直接莫队解决

    如果考虑换根的话...可以把一个操作换成小于等于9个操作就可以了

    当然怎么换,有一些非常恶心的分类讨论

    嘤嘤嘤

    YNOI 题是好题 但是要卡常 首先要fread & fwrite

    然后需要wxh的莫队写法

    然后要算一下分块大小

    sqrt(q_size) -> (n / sqrt(q_size))

    40 -> 100

    嘤嘤嘤

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline char nc()
    {
        static char buf[100000] , *p1 , *p2;
        return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
    }
    inline int read()
    {
        int ret = 0; char ch = nc();
        while(!isdigit(ch)) ch = nc();
        while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ '0') , ch = nc();
        return ret;
    }
    char pbuf[100000] , *pp = pbuf;
    inline void push(const char ch)
    {
        if(pp == pbuf + 100000) fwrite(pbuf , 1 , 100000 , stdout) , pp = pbuf;
        *pp ++ = ch;
    }
    inline void write(long long x)
    {
        static char sta[20];
        int top = 0;
        if(!x) push('0');
        while(x) sta[++top] = x % 10 ^ '0' , x /= 10;
        while(top) push(sta[top -- ]);
        push('
    ');
    }
    const int maxn = 100010;
    int n,m,rt;
    int qx;
    int a[maxn],vi[maxn];
    int q_size;
    int first[maxn],to[maxn << 1],nx[maxn << 1],cnt;
    inline void add(int u,int v)
    {
        to[++cnt] = v;
        nx[cnt] = first[u];
        first[u] = cnt;
    }
    inline void ins(int u,int v){add(u,v);add(v,u);}
    struct Q
    {
        int l,r,bl,id,opt;
        Q(){};
        Q(int _l,int _r,int _id,int _opt){l = min(_l,_r),r = max(_l,_r),id = _id,opt = _opt;}
        bool operator < (const Q &b)const
        {
            if(bl == b.bl)
            {
                if(bl & 1)
                return r < b.r;
                return r > b.r;
            }
            return l < b.l;
        }
    }qs[maxn * 45];
    int fa[maxn][23],dep[maxn],ind[maxn],oud[maxn],reh[maxn],dfn;
    inline void dfs(int x)
    {
        ind[x] = ++dfn;reh[dfn] = a[x];
        for(int i=1;i<=22;i++)
            fa[x][i] = fa[fa[x][i - 1]][i - 1];
        for(int i=first[x];i;i=nx[i])
        {
            if(to[i] == fa[x][0])continue;
            dep[to[i]] = dep[x] + 1;
            fa[to[i]][0] = x;
            dfs(to[i]);
        }oud[x] = dfn;
    }
    LL ans[maxn * 5];
    LL now;int cnt_x[maxn],cnt_y[maxn];
    inline int go_anc(int x , int y)
    {
        int i;
        for(i = 22 ; ~i ; i -- )
            if(dep[y] - dep[x] > (1 << i))
                y = fa[y][i];
        return y;
    }
    int xpos[10],ypos[10],opt_x[10],opt_y[10];
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("www.out","w",stdout);
        int tx,ty;
        n = read(),m = read();
        for(int i=1;i<=n;i++)vi[i] = a[i] = read();
        sort(vi + 1,vi + n + 1);
        for(int i=1;i<=n;i++)a[i] = lower_bound(vi + 1,vi + n + 1,a[i]) - vi;
        for(int i=2;i<=n;i++)
        {
            int u = read(),v = read();
            ins(u,v);
        }dfs(rt = 1);
        //return 0;
        for(int i=1;i<=m;i++)
        {
            int t = read(),x = read();
            if(t == 1){rt = x;continue;}
            int y = read(),z;q_size++;
            tx = ty = 0;
            if(x == rt) xpos[++tx] = n , opt_x[tx] = 1;
            else if(ind[rt] < ind[x] || ind[rt] > oud[x]) xpos[++tx] = oud[x] , opt_x[tx] = 1 , xpos[++tx] = ind[x] - 1 , opt_x[tx] = -1;
            else z = go_anc(x , rt) , xpos[++tx] = n , opt_x[tx] = 1 , xpos[++tx] = oud[z] , opt_x[tx] = -1 , xpos[++tx] = ind[z] - 1 , opt_x[tx] = 1;
            
            if(y == rt) ypos[++ty] = n , opt_y[ty] = 1;
            else if(ind[rt] < ind[y] || ind[rt] > oud[y]) ypos[++ty] = oud[y] , opt_y[ty] = 1 , ypos[++ty] = ind[y] - 1 , opt_y[ty] = -1;
            else z = go_anc(y , rt) , ypos[++ty] = n , opt_y[ty] = 1 , ypos[++ty] = oud[z] , opt_y[ty] = -1 , ypos[++ty] = ind[z] - 1 , opt_y[ty] = 1;
            
            for(int j=1;j<=tx;j++)
                for(int k=1;k<=ty;k++)
                    if(xpos[j] && ypos[k])
                        qs[++qx] = Q(xpos[j] , ypos[k] , q_size , opt_x[j] * opt_y[k]);
        }
        int si = (int)(n / sqrt(qx));
        for(int i=1;i<=qx;i++)qs[i].bl = (qs[i].l - 1) / si;
        sort(qs + 1,qs + qx + 1);
        int l = 0,r = 0;
        for(int i=1;i<=qx;i++)
        {
            while(l < qs[i].l){l++;now += cnt_y[reh[l]],cnt_x[reh[l]]++;}
            while(r < qs[i].r){r++;now += cnt_x[reh[r]],cnt_y[reh[r]]++;}
            while(l > qs[i].l){cnt_x[reh[l]]--;now -= cnt_y[reh[l]];l--;}
            while(r > qs[i].r){cnt_y[reh[r]]--;now -= cnt_x[reh[r]];r--;}
            ans[qs[i].id] += now * qs[i].opt;
        }
        for(int i=1;i<=q_size;i++)write(ans[i]);
        fwrite(pbuf , 1 , pp - pbuf , stdout);
    }
    View Code
  • 相关阅读:
    IE8上传插件jquery-form.js上传请求参数设置type为post失效问题
    路径参数汉字兼容问题
    vue-cli2移动端适配
    事件委托原生、jQuery实现
    new Date()在移动端的问题
    create-react-app配置less
    删除左右两边空格
    日期转换
    Git 常用命令
    单页面应用
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9806520.html
Copyright © 2011-2022 走看看