zoukankan      html  css  js  c++  java
  • CSU-2214 Sequence Magic

    题目链接

    http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2214

    题目

    Description

    有一个1到N的自然数序列1,2,3,...,N-1,N。

    我们对它进行M次操作,每次操作将其中连续的一段区间 [Ai,Bi][Ai,Bi] (即第Ai个元素到第Bi个元素之间的一段)取出,然后插入到剩下的第Ci个元素的后面,如果Ci=0,表示插入到最左端。

    现在,M次操作完后,有K个询问,每个询问Pi表示询问最终第Pi个元素是几。你的任务是写一个程序,依次回答这K个询问。

    Input

    第一行三个数,N,M,K。

    接下来M行,每行三个整数Ai,Bi,Ci。

    接下来K行,每行一个正整数Pi。

    1<=N<=(10^9),1<=M<=(10^4),1<=K<=1000,1<=Ai<=Bi<=N,0<=Ci<=N-(Bi-Ai+1),1<=Pi<=N;

    Output

    输出共K行,为每次询问的答案。

    Sample Input

    13 3 13 
    6 12 1 
    2 9 0 
    10 13 8 
    1 
    2 
    3 
    4 
    5 
    6 
    7 
    8 
    9 
    10 
    11 
    12 
    13
    

    Sample Output

    6 
    7 
    8 
    9 
    10 
    11 
    12
    2 
    3 
    4 
    5 
    13 
    1 
    

    题解

    由于k,m都很小,所以我们可以考虑离线的思想离线的思想,对于每一次询问,从m到1把区间平移操作恢复。我们要知道的是最后序列的第x个数,那么我们可以算出不做最后一次平移前x是第几个位置,这样倒退到第一次就是一开始x所在的位置,也就是x所对应的数,输出答案即可。

    考虑一下怎么算,有两种情况(c[j] ge a[j])时,我们把(a[j]...b[j])移动到(c[j])后面,此时若x在(a[j],c[j])之间,那么他就会向后移动(b[j]-a[j]+1)个数,如果它在(c[j]+1,c[j]+b[j]-a[j]+1)之间,那么设这次位置是x,恢复平移后位置为y,那么(a[j]+(x-c[j])-1=y),即x+=a[j]-c[j]-1。其他情况x不变

    (c[j]<a[j]),此时若x在(c[j]+1,c[j]+b[j]-a[j]+1)之间,那么x+=a[j]-c[j]-1,若x处在(c[j]+1+b[j]-a[j]+1,b[j])之间,那么(x=c[j]+x-(c[j]+b[j]-a[j]+1))即x+=a[j]-b[j]-1。

    一直倒推到1即为答案,依次输出即可

    AC代码

    #include<bits/stdc++.h>
    #define N 10050
    using namespace std;
    int a[N], b[N], c[N];
    typedef long long ll;
    int main() {
    	int n, m, k;
    	scanf("%d%d%d", &n, &m, &k);
    	for (int i = 1; i <= m; i++) {
    		scanf("%d%d%d", &a[i], &b[i], &c[i]);
    	}
    	for (int i = 1; i <= k; i++) {
    		ll x;
    		scanf("%lld", &x);
    		for (int j = m; j >= 1; j--) {
    			if (c[j] >= a[j]) {
    				if (x >= a[j] && x <= c[j]) {
    					x += b[j] - a[j] + 1;
    				}
    				else if (x >= c[j] + 1 && x <= c[j] + b[j] - a[j] + 1) {
    					x += a[j] - c[j] - 1;
    				}
    			}
    			else {
    				if (x >= c[j] + 1 && x <= c[j] + b[j] - a[j] + 1) {
    					x += c[j] + 1 + a[j] - c[j] - 1 - 1 - c[j];
    				}
    				else if (x >= c[j] + b[j] - a[j] + 1 + 1 && x <= b[j]) {
    					x -= (b[j] - a[j] + 1);
    				}
    			}
    		}
    		printf("%d
    ", x);
    	}
    }
    /**********************************************************************
    	Problem: 2214
    	User: Artoriax
    	Language: C++
    	Result: AC
    	Time:284 ms
    	Memory:2140 kb
    **********************************************************************/
    
    

    结语

    至此所有寒假集训选拔写过的题的题解补完了,赶快开始补寒假集训的题解了,不能再划水了

  • 相关阅读:
    kvm系列之二:kvm日常管理
    kvm系列之一:构建kvm虚拟机(centos7)
    cobbler无人值守安装
    判断我们的服务器是物理机还是虚拟机
    kickstark无人值守安装
    找回密码之单用户模式
    rsync传输引起的网络延迟
    题解 P3628 【[APIO2010]特别行动队】
    题解 P3211 【[HNOI2011]XOR和路径】
    题解 POJ1094 【Sorting It All Out】
  • 原文地址:https://www.cnblogs.com/artoriax/p/10372535.html
Copyright © 2011-2022 走看看