1208B
题意:给你一个序列,让你删掉一个子串,问你怎样删,留下的部分是最长的不重复子序列。
思路:看的晓阳队的思想。问的是求删掉的子串,那么我们转化成 求剩下的最长不重复子串。
因为剩下的可能是右边一段或者左边一段或者两边合起来!所以:
离散化后复制一份放后面,然后尺取法求序列中间的最长不重复。
但是能做答案的只能是l从1开始或者横跨n和n+1的!
想想为什么。
因为只能删掉中间的
如果取中间的一段最长不重复子串 就得从两边拿 显然是不可能的
so要有l==1或者r>=n的限制(r可取n 是右部区间。r大于n 是右边与左边连续区间
才能作为最大值。
下面是AC代码。尺取法
离散化是nlogn的复杂度
尺取法是On的复杂度,可以接受。
还有就是不要只在增加为1的时候才去判,若增加为2再取收缩时 也有可能是最大!
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define sdd(a,b) scanf("%d%d",&a,&b)
#define cl(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define dbg() printf("aaa\n")
using namespace std;
//注意开二倍数组!!!!
int a[4010],acopy[2010];
int num[2010];
int main() {
int n;
cl(num,0);
sd(n);
rep(i,1,n){
sd(a[i]);
acopy[i]=a[i];
}
sort(acopy+1,acopy+n+1);
int size=unique(acopy+1,acopy+n+1)-(acopy+1);//注意这里!!!
rep(i,1,n){
a[i]=lower_bound(acopy+1,acopy+size+1,a[i])-acopy;
}
rep(i,1,n){//复制一遍
a[n+i]=a[i];
}//然后找最长不重复子序列
int l=1,r=1;
int len=0;//最长不重复子序列
while(l<=n){//无需刻意控制长度为n 因为长度一定为n
num[a[r]]++;
while(num[a[r]]>1){
num[a[l]]--;
l++;
}
if(l==1||r>=n) {
if(len<r-l+1) len=r-l+1;
}
r++;
}
printf("%d\n",n-len);
return 0;
}
/*
10
1 100 100 1000 1000 100 10 1 1000 1
*/
1208C
题意:给你一个数n(n是4的倍数)
让你构造一个n* n的矩阵,满足行列异或和相等
思路:刚刚拿到这个题 是真的不会。。。
后来看了题解发现
首先因为某个数和自己异或 一定是0!
所以说我们只要安排,两个相同的数在同一行列就行了
注意 ,而这里不能相同。
但是我们可以让它们高位相同
什么意思?
来看:因为方阵n一定为4的倍数
所以说我们先把方阵分成四个部分
每个部分的都是n/2的方阵 而n/2一定是2的倍数!(这点很重要)
我们要做的是,四个小方阵,每个的同一位置,放相同的数*4,再各自加上0 1 2 3
什么道理?
乘以四就是各自左移两位,这样做保证了每行/列 高位有两个相同的数,低位有偶数个0/1/2/3!
这样每行每列异或和都为0!
思路写的很乱,总之就是,大方阵分成四个小方阵,每个小方阵每个相同位置的数 高位相同 低位分别是0 1 2 3 然后又因为每个小方阵都是偶数阶 所以保证了低位可以是偶数个相同的数异或 高位也有n/2个相同的数异或 最终异或结果都是0
下面是ac代码
int mp[1010][1010];
int main() {
int n;
sd(n);
//应该是确定四分之一然后确定其他 而不是确定4x4再确定其他- -这个也行?
int cnt=0;
rep(i,1,n/2){//有了思路其实还挺好想的
rep(j,1,n/2){//也就刚好是4的倍数 不然8 9都不行
mp[i][j]=cnt*4;
mp[i][j+n/2]=cnt*4+1;
mp[i+n/2][j]=cnt*4+2;
mp[i+n/2][j+n/2]=cnt*4+3;
cnt++;
}
}
rep(i,1,n){
rep(j,1,n){
printf("%d%c",mp[i][j],j==n?'\n':' ');
}
}
return 0;
}