列表

详情


NC21118. 小睿睿的询问

描述

小睿睿的n个妹纸排成一排,每个妹纸有一个颜值val[i]。有m个询问,对于每一个询问,小睿睿想知道区间[L,R]颜值最高而编号最小的妹纸是哪一个
对于妹纸们的颜值val[i],其生成函数为:
void generate_array(int n,int seed) {     unsigned x = seed;     for (int i=1;i<=n;++i)     {         x ^= x << 13;         x ^= x >> 17;         x ^= x << 5;         val[i]=x%100;     } }
对于每一组询问,区间[L,R]的生成函数为:
void generate_ask(int n,int m,int seedx,int seedy) {     unsigned x=seedx,y=seedy;     for (int i=1;i<=m;++i)     {         x ^= x << 13;         x ^= x >> 17;         x ^= x << 5;         y ^= y << 13;         y ^= y >> 17;         y ^= y << 5;         L=(x^lastans)%n+1,R=(y^lastans)%n+1;         if (L>R)swap(L,R);         //解决询问     } }

其中lastans为上个询问的答案,对于第一个询问,lastans为0

输入描述

第1行2个整数n,m,分别表示序列长度和询问次数

第2行3个整数seed,seedx,seedy,意义如题所示

输出描述

一行一个整数,表示所有询问的答案的异或和

示例1

输入:

10 5
3 5 7

输出:

2

说明:

生成序列:

7 11 47 53 3 7 63 36 55 55

各组询问及答案:

询问:4 6

该询问答案:4

询问:2 6

该询问答案:4

询问:2 2

该询问答案:2

询问:4 8

该询问答案:7

询问:1 9

该询问答案:7

所有询问的答案的异或和:2

示例2

输入:

100000 10000000
1 2 3

输出:

5042

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 1708ms, 内存消耗: 9084K, 提交时间: 2019-03-21 17:48:18

#include<cstdio>
#include<iostream>
using namespace std;
int value[100005]={0},n,m,seed,seedx,seedy,st[500005][20]={0},lo[100005];
int ans,lastans;
void get_array()
{
	unsigned x=seed;
	for (int i=1;i<=n;i++)
	{
		x^=x<<13;
		x^=x>>17;
		x^=x<<5;
		value[i]=x%100;
		x%=1ll<<40;
	}
}
int ask(int l,int r)
{
	int len=r-l+1;
	if (value[st[l][lo[len]]]>=value[st[r-(1<<lo[len])+1][lo[len]]]) return st[l][lo[len]];else return st[r-(1<<lo[len])+1][lo[len]];
}
void get_st()
{
	for (int i=1;i<=n;i++) st[i][0]=i;
	for (int i=1;i<=lo[n];i++) for (int j=1;j<=n;j++) if (value[st[j][i-1]]>=value[st[j+(1<<(i-1))][i-1]]) st[j][i]=st[j][i-1];else st[j][i]=st[j+(1<<(i-1))][i-1];
}
void get_ask()
{
	unsigned x=seedx,y=seedy;
	int l,r,temp;
	for (int i=1;i<=m;i++)
	{
		x^=x<<13;
		x^=x>>17;
		x^=x<<5;
		x%=1ll<<40;
		y^=y<<13;
		y^=y>>17;
		y^=y<<5;
		y%=1ll<<40;
		l=(x^lastans)%n+1;
		r=(y^lastans)%n+1;
		if (l>r)
		{
			temp=l;
			l=r;
			r=temp;
		}
		lastans=ask(l,r);
		ans^=lastans;
	}
}
int main()
{
	scanf("%d%d%d%d%d",&n,&m,&seed,&seedx,&seedy);
	for (int i=0;i<20;i++) for (int j=(1<<i);j<(1<<(i+1))&&j<=n;j++) lo[j]=i;
	get_array();
	get_st();
	get_ask();
	printf("%d",ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 638ms, 内存消耗: 7148K, 提交时间: 2019-02-26 21:53:46

#include<bits/stdc++.h>
#define REP(i, a, b) for(unsigned i(a); i <= (b); ++i)
const int N(1e5 + 5);
unsigned w[N], st[18][N];
inline unsigned get(unsigned i, unsigned j){
    if(w[i] == w[j])return i < j ? i : j;
    return w[i] > w[j] ? i : j;
}
int main(){
    unsigned n, m, a, b, c;
    scanf("%u%u%u%u%u", &n, &m, &a, &b, &c);
    REP(i, 1, n){
        a ^= a << 13, a ^= a >> 17, a ^= a << 5;
        st[0][i] = i, w[i] = a % 100;
    }
    REP(i, 1, 17)REP(j, 1 << i, n)st[i][j] = get(st[i - 1][j], st[i - 1][j - (1 << i - 1)]);
    unsigned ans = 0, res = 0;
    while(m--){
        b ^= b << 13;
        b ^= b >> 17;
        b ^= b << 5;
        c ^= c << 13;
        c ^= c >> 17;
        c ^= c << 5;
        unsigned l = (b ^ ans) % n + 1, r = (c ^ ans) % n + 1, k;
        if(l > r)std::swap(l, r);
        k = std::__lg(r - l + 1);
        res ^= ans = get(st[k][r], st[k][l + (1 << k) - 1]);
    }
    std::cout << res;
    return 0;
}

上一题