首页 > 其他分享 >Codeforces Round #778 (Div. 1 + Div. 2, based on Technocup 2022 Final Round) F Minimal String Xorati

Codeforces Round #778 (Div. 1 + Div. 2, based on Technocup 2022 Final Round) F Minimal String Xorati

时间:2022-11-04 16:24:21浏览次数:43  
标签:based int res mid long ull Div Round

A-E 都还是比较简单的。

首先,容易想到的,异或上 \(2^k\),相当于以 \(2^{k+1}\) 的长度分块,然后每一块对半切,然后交换左右部分。

我的想法是由于这个交换的性质,也许我们可以尝试着快速计算哈希值。

显然有 \(h(x,2^k,i)=h(x,2^{k-1},i)+h(x \ \text{xor} \ 2^{k-1},2^{k-1},i)\),\(h(x,k,i)\) 表示异或上 \(x\),长度为 \(2^k\),左端点为 \(i\),这个区间的哈希值。

不过你现在好像必须 \(O(n^2)\) 以上取计算每个状态!

于是你考虑能否交换,使得查询区间成为前缀区间,然后我们只记录前缀区间的哈希值即可。

显然你可以写一份暴力,每次判断查询区间是否与 0 分居两侧,是的话就换。写出来后发现 \(x=x\ \text{xor} \ i\) 即可。

#pragma GCC optimize("Ofast","-funroll-loops")
#pragma GCC target("sse4.1","sse4.2","ssse3","sse3","sse2","sse","avx2","avx","popcnt","tune=native")
#include <bits/stdc++.h>
//#define int long long
#define ull unsigned long long
#define pb push_back
using namespace std;
const ull base=19260817;
const int N=(1<<18)+5;
//map<int,ull>mp[N][19];
ull h[N][19];
ull v[26],pw[N];
char s[N];
int n,m,M;
mt19937 RAND(time(0));

ull cal(ull x) {
	return x*x*x*x+2*x*x*x+3*x*x+4*x+7+M;
}

ull dfs(int x,int k,int i) { //i\to 0
//	for(int t=1;t<=m+1;t++) {
//		for(int p=m;p>=0;p--) {
//			int l=(1<<p),r=(1<<(p+1))-1;
////			if(l<=i&&(i+(1<<k)-1)<=r) {
//			if((i>>p)&1) {
//				x^=(1<<p);
//				i-=l;
//			}
//		}
		x^=i;
//		cout<<i<<" "<<h[x][k]<<'\n';
		return h[x][k];
//	}
}

ull get(int x,int l,int r) {
	int qwq=(r-l+1),nw=l; ull res=0;
	for(int i=m;i>=0;i--) {
//		cout<<nw<<" "<<res<<" "<<l<<" "<<r<<'\n';
		if((qwq>>i)&1) {
			res=res*pw[(1<<i)]+dfs(x,i,nw);
			nw+=(1<<i);
		}
	}
	return res;
//	ull res=0;
//	for(int i=l;i<=r;i++) res=res*base+s[i^x]-'a';
//	cout<<x<<" "<<l<<" "<<r<<" "<<res<<'\n';
//	return res;
}

bool cmp(int x,int y) {
	int l=0,r=n-1,res=-1;
	while(l<=r) {
		int mid=(l+r)>>1;
		if(get(x,0,mid)==get(y,0,mid)) res=mid,l=mid+1;
		else r=mid-1;
	}
	
	if(res==n-1) return 0;
	++res;
//	cout<<x<<" "<<y<<" "<<res<<" "<<s[res^x]<<" "<<s[res^y]<<'\n';
	if(s[res^x]<s[res^y]) return 1;
	return 0;
}

signed main() {
	cin.tie(0); ios::sync_with_stdio(false);
	cin>>m>>s; n=(1<<m);
	M=RAND()%10;
	for(int i=0;i<26;i++) v[i]=cal(cal(cal(cal(cal((ull)i)))));
	pw[0]=1;
	for(int i=1;i<=n;i++) pw[i]=pw[i-1]*base;
	for(int i=0;i<n;i++) {
//		for(int j=0;j<n;j++) {
//			h[i][0][j]=v[s[j^i]-'a'];
//		}
		h[i][0]=v[s[i]-'a'];
	}
	for(int k=1;k<=m;k++) {
		int len=(1<<k);
		for(int x=0;x<n;x++) {
//			for(int i=0;i<n;i+=len) {
//				h[x][k][i]=h[x][k-1][i]*pw[len/2]+h[x^(1ll<<(k-1))][k-1][i];   
//			}
			h[x][k]=h[x][k-1]*pw[len/2]+h[x^(1<<(k-1))][k-1];
		}
	}
	int ans=0;
	for(int i=1;i<n;i++) {
		if(cmp(i,ans)==1) 
//		{
//			for(int j=0;j<=m;j++) map<int,ull>().swap(mp[ans][j]);
			ans=i;
//		} else {
//			for(int j=0;j<=m;j++) map<int,ull>().swap(mp[i][j]);
//		}
	}
//	cout<<ans<<'\n';
	for(int i=0;i<n;i++) cout<<(char)(s[i^ans]);
	return 0;
} 

标签:based,int,res,mid,long,ull,Div,Round
From: https://www.cnblogs.com/xugangfan/p/16858210.html

相关文章

  • Codeforces Round #766 (Div. 2)
    CodeforcesRound#766(Div.2)\(\color{Green}{★}\)表示赛时做出。\(\color{Yellow}{★}\)表示赛后已补。\(\color{Red}{★}\)表示\(\text{To\be\solved}\)......
  • Codeforces Round #820 (Div. 3) F
    F.KireiandtheLinearFunction首先我们知道的是给定长度w都是%9意义下的所以我们枚举四个位置的数就是9^4预处理出来答案这里我们要去w长度的串%9但是w的位数过......
  • 基于gamebased算法的动态频谱访问matlab仿真
    目录一、理论基础二、核心程序三、测试结果一、理论基础随着越来越多的新型无线应用,对频谱资源的需求越来越大。在这种情况下,这是举世公认的认知无线电的出现已经成为......
  • Codeforces Global Round 20 D F1 F2/more
    https://codeforc.es/contest/1672F1https://www.luogu.com.cn/blog/AlexWei/solution-cf1672f1将置换分解为若干轮换(环),悲伤值越大\(\Rightarrow\)环越少(设环为\(k......
  • Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2) D
    D.ExplorerSpace我们考虑一个性质就是他最多就是找到一条k/2的最短路径然后回来这样是肯定是包含最优解的这个观察第二个样例我们将其改变一下要是我们一半的长度......
  • Manthan, Codefest 18 (rated, Div. 1 + Div. 2) (E,F,G)
    LinkEm次操作,每次加边后询问最大旅行团。旅行团的定义:旅行团中的每个人都至少有k个邻接点在团里。显然会肯定很想全选,但是有的人压根没有k个邻接点,只能直接删掉,然后一......
  • Codeforces Round #610 (Div. 2) C
    C.PetyaandExamhttps://codeforces.com/contest/1282/problem/C考虑贪心先对于时间排序然后贪心我们可以不考那我们可以在此之前离开然后在离开之前这段时间多做......
  • np.divide()
    用例:numpy.divide(x1,x2,/,out=None,*,where=True,casting=‘same_kind’,order=‘K’,dtype=None,subok=True[,signature,extobj])=<ufunc‘true_divide’......
  • Codeforces Round #634 (Div. 3) E
    E2.ThreeBlocksPalindrome(hardversion)我们考虑一种最优构造对于一个数x我们肯定要的是他的前几个再最后几个中间选最多的一个数这样显然是最优的我们枚举x......
  • Codeforces Global Round 7 D
    D1.Prefix-SuffixPalindrome(Easyversion)easy版本我们只需要n2dp预处理出快速判断回文串然后我们再通过双指针O(n)求解最大串intdp[5010][5010];voidsolve(){......