• UVA 12657 Boxes in a Line


    https://vjudge.net/problem/UVA-12657

    题目

    你有一行盒子,从左到右依次编号为1, 2, 3,…, n。你可以执行四种指令:

    • 1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令)。
    • 2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令)。
    • 3 X Y表示交换盒子X和Y的位置。
    • 4 表示反转整条链。

    指令保证合法,即X不等于Y。例如,当n=6时在初始状态下执行1 1 4后,盒子序列为2 3 1 4 5 6。接下来执行2 3 5,盒子序列变成2 1 4 5 3 6。再执行3 1 6,得到2 6 4 5 3 1。最终执行4,得到1 3 5 4 6 2。

    样例输入

    6 4
    1 1 4
    2 3 5
    3 1 6
    4
    6 3
    1 1 4
    2 3 5
    3 1 6
    100000 1
    4
    

    样例输出

    Case 1: 12
    Case 2: 9
    Case 3: 2500050000
    

     题解

    显然要用链表,然后估计等差数列的和上界为最后一项平方,即$ans=O(n^2)$(即使除以2也不影响次数)

    那么答案上界是$10^{10}$,爆 int ,所以答案用 long long 存。(样例也好心地提醒了……可是还是没注意)

    然后就画图比较……

    定义双向链表

    然后1和2操作可以对照图来了……

    如 1 B D, 1 B C

    3操作也可以对照图来……

    需要考虑两个是否相邻,验证后发现用这种策略也不会出错……

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #define REP(i,x,y) for(register int i=x; i<y; i++)
    #define REPE(i,x,y) for(register int i=x; i<=y; i++)
    #ifdef LOCAL
    #define DBG(a,...) printf(a, ##__VA_ARGS__)
    #else
    #define DBG(a,...) (void)0
    #endif
    
    template <class T>
    inline void read(T& x) {
        char c=getchar();int f=1;x=0;
        while(!isdigit(c)&&c!='-')c=getchar();if(c=='-')f=-1,c=getchar();
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
    }
    template <class T,class... A>void read(T&t,A&...a){read(t);read(a...);}//C++11可用
    
    #define MAXN 100007
    int point[MAXN], nxt[MAXN], prv[MAXN];
    
    int main() {
    	int n, m;
    	int kase=0;
    	while(~scanf("%d%d", &n, &m)) {
    		kase++;
    		bool rev = false;
    		REPE(i,1,n) {
    			point[i]=i;
    			nxt[i]=i+1;
    			prv[i]=i-1;
    		}
    		nxt[n]=-1;
    		nxt[0]=1;
    		prv[1]=-1;
    		prv[0]=n;
    		REP(i,0,m) {
    			int op; read(op);
    			if(op==4) {
    				rev = !rev;
    //				DBG("%d
    ", op);
    				continue;
    			}
    			int *p = rev?nxt:prv;
    			int *n = rev?prv:nxt;
    			int x,y; read(x,y);
    			if(op!=3) {
    				int _p=p[x], _n=n[x];
    				if(~_p) n[_p]=_n; else n[0]=_n;
    				if(~_n) p[_n]=_p; else p[0]=_p;
    				_p=p[y], _n=n[y];
    				if(op==1) {
    					if(~_p) n[_p]=x; else n[0]=x;
    					p[x]=_p;
    					n[x]=y;
    					p[y]=x;
    				} else {
    					n[y]=x;
    					p[x]=y;
    					n[x]=_n;
    					if(~_n) p[_n]=x; else p[0]=x;
    				}
    			} else {
    				int _p=p[x], _n=n[x], _py=p[y], _ny=n[y];
    				if(~_p) n[_p]=y; else n[0]=y;
    				if(~_n) p[_n]=y; else p[0]=y;
    				if(~_py) n[_py]=x; else n[0]=x;
    				if(~_ny) p[_ny]=x; else p[0]=x;
    				swap(p[x],p[y]);
    				swap(n[x],n[y]);
    			}
    		}
    //		int *p = rev?nxt:prv;
    		int *n = rev?prv:nxt;
    		long long ans=0;
    		for(int i=n[0],j = 1; ~i; i=n[i],j++) {
    //			DBG("%d ", i);
    			if(j&1) {
    				ans+=i;
    			}
    		}
    		printf("Case %d: %lld
    ", kase, ans);
    	}
    	
    	return 0;
    }
    

    比紫书的操作要简单一些(吧)

    还是要画图

  • 相关阅读:
    【BZOJ 3144】 [Hnoi2013]切糕
    【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏
    【BZOJ 4016】[FJOI2014]最短路径树问题
    【BZOJ 2152】 聪聪可可
    【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏 括号序列
    【BZOJ 3196】 Tyvj 1730 二逼平衡树 分块
    【BZOJ 2038】 [2009国家集训队]小Z的袜子(hose)
    【BZOJ 3196】 Tyvj 1730 二逼平衡树
    接下来的事
    【BZOJ 1189】 [HNOI2007]紧急疏散evacuate
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10387241.html
Copyright © 2020-2023  润新知