HDU5063 - Operation the Sequence(离线处理)

题目链接 :HDU5063

【题意】有一个序列a1,a2,a3... an (n<=10000);m次操作,有4种,分别在函数对应3种修改和每次q i询问当前a[i]的值。

【分析】正向操作肯定超时;看到最多只有50次查询,所以首先把所有查询记录下来,然后分别针对每次查询的位置反推出开始位置,就可以在50*100000复杂度内完成。对于函数3直接模拟就可以了,主要是把函数1和2要在O(1)时间内处理完,找下规律就可以发现:

函数1:找到一个中间分割位置mid=n-n/2; 可以发现<=mid的位置要推出上一个位置都是+0,+1,+2... +mid-1,也就是

x =  x+(x-1);    然后在>mid位置时也是-(mid-1),-(mid-2),...-1,所以好像可以推出公式 x = x-(n-x+1);但是当n为偶数时公式为x = x-(n-x),所以合并为x = x-(n-x+(n&1));

函数2: 很容易找到公式为x = n-x+1;

 

【AC CODE】 281ms

#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
#define min(a,b) (a>b?b:a)
#define max(a,b) (a>b?a:b)
#define MAXN 100010
#define MOD 1000000007
struct NODE{//输入数据
	char ch;
	int num;
}a[MAXN];
struct Q{//所有查询
	int si,x,cnt;
	Q(int a, int b, int c){si = a, x = b, cnt = c;}
};
vector<Q> q;

int main()
{
#ifdef SHY
    freopen("e:\\1.txt","r",stdin);
#endif
	int t;
	scanf("%d%*c", &t);
	while(t--)
	{
		int n,m, cnt = 0,num;
		scanf("%d %d%*c", &n, &m);
		char ch;
		q.clear();
		rep(i,0,m)
		{
			scanf("%c %d%*c", &ch, &num);
			if('O' == ch && 3 == num) cnt++;
			else if('Q' == ch) q.push_back(Q(i,num,cnt));
			a[i].ch = ch, a[i].num = num;
		}
		int sz = q.size(), mid = n-n/2;
		rep(i,0,sz)
		{
			int x = q[i].x;
			per(j,q[i].si-1,0)
			{
				if('Q' == a[j].ch) continue;
				if(1 == a[j].num)
				{
					if(x <= mid) x += x-1;
					else x -= n-x+(n&1);
				}
				else if(2 == a[j].num)
					x = n-x+1;
			}
			long long ans = x;
			rep(j,0,q[i].cnt)
				ans = ans*ans%MOD;
			printf("%I64d\n", ans);
		}
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值