• 【分块优化】H. Permutation and Queries


    【分块优化】H. Permutation and Queries

    给定一个序列ne。

    ne[i]代表着若当前位置为i的下一个跳转的位置为ne[i],比如ne[3]=5代表着说当前位置为3的下一个要跳转到的位置为5.

    并进行q次操作,操作类型分为两种。

    • 一种是swap(ne[i],ne[j])
    • 另外一种是move(x,k),需要输出将x=ne[x]进行k次迭代后的结果。

    思路:

    使用分块维护x在跳转\(int(\sqrt q)\)后的结果。

    在使用swap操作后要进行更新维护。

    (类似对两个链表交换中间某两个结点的操作)

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    using namespace std;
    const int N = 3E5+5,M = 6E5+10;
    int n,m,q,ne[N],pre[N],jmp[N],len,opt,x,y;
    inline int move(int x,int k)
    {
    	repd(i,1,k) x = ne[x];
    	return x; 
    }
    inline void modi(int st)
    {
    	int fin = st;
    	repd(i,1,len-1) st = pre[st];
    	fin = ne[fin];
    	repd(i,1,len) 
    	{
    		jmp[st] = fin;
    		st = ne[st];
    		fin = ne[fin];
    	}
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>q;
        len = int(sqrt(n));
        repd(i,1,n) cin>>ne[i];
        repd(i,1,n) pre[ne[i]] = i;
        repd(i,1,n) jmp[i] = move(i,len);
    	repd(i,1,q)
        {
            cin>>opt>>x>>y;
            if(opt==1)
            {
               swap(pre[ne[x]],pre[ne[y]]);
    		   swap(ne[x],ne[y]);
    		   modi(x);modi(y); 	
    		}
    		else if(opt==2)
    		{
    		    while(y-len>=0) x = jmp[x],y -= len;
    		    cout<<move(x,y)<<endl;
    		}
    	}
        return 0;
    }
    
    
  • 相关阅读:
    JCreator的配置
    哈夫曼编码
    最小生成树
    逻辑左移右移与算术左移右移
    原码 反码 补码 移码
    hdu 小希的迷宫
    (二)Qt窗口应用程序Widget
    (一)Qt5模块,QtCreator常用快捷键,命名规范
    if __name__="__main__"
    数据库之sql语句汇总
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/16033227.html
Copyright © 2020-2023  润新知