B题
题意:给出n个数,两种操作。
M x y:求区间[x,y]的和
S x r:将x更新为r
思路:线段树
#include <cstdio>
#include <cstring>
#define maxn 200000 + 5
using namespace std;
int c[maxn], a[maxn];
int n,t;
int Lowbit(int x) // 2^k
{
return x&(-x);
}
void update(int i, int x)//i点增量为x
{
while(i <= n)
{
c[i] += x;
i += Lowbit(i);
}
}
int sum(int x)//区间[1,x]求和
{
int sum=0;
while(x>0)
{
sum+=c[x];
x-=Lowbit(x);
}
return sum;
}
int Getsum(int x1,int x2) //求任意区间和
{
return sum(x2) - sum(x1-1);
}
int main()
{
int cnt = 0, i, j;
while(~scanf("%d",&n))
{
if(n == 0) break;
cnt++;
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
for(i = 1; i <= n; i++) //i必须从1开始
{
scanf("%d",&a[i]);
update(i,a[i]);
}
if(cnt != 1) printf("\n");
printf("Case %d:\n",cnt);
char oper[5];
while(~scanf("%s",oper))
{
if(strcmp(oper,"END")==0){
break;
}
scanf("%d%d",&i,&j);
if(strcmp(oper,"M")==0)
{
if(i == 1) printf("%d\n",sum(j));
else printf("%d\n",Getsum(i,j));
}
if(strcmp(oper,"S")==0)
{
update(i,j-a[i]);
a[i] = j;
}
}
}
return 0;
}
D题
题意:给出一个字符串str,求出str中存在多少子串,使得这些子串既是str的前缀,又是str的后缀。从小到大依次输出这些子串的长度。
思路:kmp的next数组运用,求出末尾的next值,并递归的向下求出所有的next值。
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 400000 + 5;
int next[N];
char s[N];
int len;
//get next arr
void getNext(char *T)
{
int j,k;
int len = strlen(T);
j = 0;
k = -1;
next[0] = -1;
while(j < len) {
if(k == -1 || T[j] == T[k])
next[++j] = ++k;
else
k = next[k];
}
}
void print(int i)
{
if(next[i] > 0) {
print(next[i]);
printf("%d ", next[i]);
}
}
int main()
{
while(~scanf("%s",s)) {
len = strlen(s);
getNext(s);
print(len);
printf("%d\n", len);
}
return 0;
}
E题
题意:给出n个数,其中任意三个数si,sj,sk,求(si+sj)^sk最大值。
思路:其实暴力也能过。01字典树。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 1000 + 10;
const int maxnode = 100000 + 10;
int a[maxn];
int ch[maxnode][2];
int val[maxnode];
int sz,n,t;
void init(){
sz=1;
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
}
void add(int x,int v){
int p = 0;
for(int i=31;i>=0;i--){
int id = (x>>i)&1;
if(ch[p][id]==0){
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[p][id]=sz++;
}
p = ch[p][id];
val[p]+=v;
}
}
void Delete(int x)
{
int u = 0, v;
for(int i = 31; i >= 0; i--)
{
v = (x & (1 << i)) ? 1 : 0;
u = ch[u][v];
val[u]--;
}
}
int Query(int x){
int ans = 0,u = 0;
x = ~x;
for(int i=31;i>=0;i--){
ans*=2;
int id = (x>>i)&1;
if(ch[u][id]&&val[ch[u][id]]){
ans++;
u = ch[u][id];
}
else
u = ch[u][1-id];
}
return ans;
}
int main()
{
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
init();
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
add(a[i],1);
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
Delete(a[i]);
for(int j = i+1; j <= n; j++)
{
Delete(a[j]);
ans = max(ans, Query(a[i]+a[j]));
add(a[j],1);
}
add(a[i],1);
}
printf("%d\n",ans);
}
return 0;
}
感觉自己有点应付了事了,有心思再修改,剩下的慢慢补吧。