CF上的一場資格賽,有二十四小時的時間給我們做,所以爲了晉級,我和隊友合力弄掉了四題,而最後的E題其實也不難,後來也過了……因爲A,B相對較水,所以以下只講後三題……
C題:
比賽時一致認爲暴力不行,比賽後發現很多都是暴力過的……因此,比賽時用到了樹狀數組……其實是隊友做出的,無限YM……不過樹狀數組真是個好東西啊……
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define M (1<<18)
int cl[26][M]; //cl[i][j]表示的是第i種字母在數高爲j裏的數目
int lowbit(int x)
{
return x&(-x);
}
void add(int id,int pos,int v)
{
while(pos<M)
{
cl[id][pos]+=v;
pos+=lowbit(pos);
}
}
int find(int id,int x)
{
int i,ans,cnt;
ans=cnt=0;
for(i=18;i>=0;i--)
{
ans+=(1<<i);
if(ans>=M||cnt+cl[id][ans]>=x)ans-=(1<<i);
else cnt+=cl[id][ans];
}
return ans+1;
}
int main()
{
//freopen("a.txt","r",stdin);
int i,k,n,x,id,pos,len;
char c;
string s,str;
cin>>n>>s;
str="#";
for(i=0;i<n;i++)str+=s;
len=str.size();
for(i=1;i<len;i++)
{
id=str[i]-'a';
add(id,i,1); //建樹
}
cin>>k;
while(k--)
{
cin>>x>>c;
id=c-'a';
pos=find(id,x); //找此點目前的位置
str[pos]='#';
add(id,pos,-1); //刪點
}
for(i=0;i<len;i++)
{
if(str[i]=='#')continue;
cout<<str[i];
}
cout<<endl;
return 0;
}
D題:
這題是一道挺好的dp,裏面的數組f[i][j]表示的是字符串i到j的迴文的數目,sum[i]表示的是i後面(包括i)的迴文的數目……
#include<iostream>
using namespace std;
__int64 f[2005][2005];
int main()
{
//freopen("a.txt","r",stdin);
__int64 i,j,k,l,len,sum[2005];
char s[2005];
scanf("%s",s);
len=strlen(s);
memset(f,0,sizeof(f));
for(i=0;i<len;i++)f[i][i]=1; //只有一個字符時,迴文數爲1
for(i=1;i<len;i++) //i表示間距
for(j=0;i+j<len;j++)
{
k=i+j;
if(s[j]==s[k])
{
if(i==1)f[j][k]=1;
else f[j][k]=f[j+1][k-1]; //只有j和k中間的那一段是迴文,j到k纔是迴文
}
}
memset(sum,0,sizeof(sum));
for(i=0;i<len;i++)
for(j=i;j<len;j++)
sum[i]+=f[i][j]; //這時sum[i]以i爲起點的後面的迴文數
for(i=0;i<len;i++)
for(j=i+1;j<len;j++)
sum[i]+=sum[j]; //這裏sum[i]加上i後面不同起點的迴文數
l=0;
for(i=0;i<len;i++)
for(j=i;j<len;j++)
if(f[i][j])l+=sum[j+1];
printf("%I64d\n",l);
return 0;
}
E題:
超級模擬題,不多說,直接看代碼……
#pragma warning(disable:4786)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
using namespace std;
struct T
{
int c,d;
__int64 h;
}p[100005];
bool cmp(T x,T y)
{
return x.c!=y.c?x.c<y.c:x.h>y.h;
}
__int64 h1[100005],h2[100005],a2[100005];
vector<int> g,a1[100005];
vector<T> v[100005];
map<int,int> m;
int main()
{
//freopen("a.txt","r",stdin);
int d,i,j,k,l,s,n,y1,y2,len,i1,j1,y3,y4;
__int64 w,x1,x2,Max;
T t;
m.clear();
scanf("%d",&n);
for(i=0;i<n;i++)v[i].clear();
for(i=0;i<n;i++)
{
scanf("%d%I64d",&p[i].c,&p[i].h);
p[i].d=i+1;
}
sort(p,p+n,cmp);
d=p[0].c;
l=1;
m[d]=l++;
for(i=1;i<n;i++)
if(p[i].c!=d)
{
d=p[i].c;
if(!m[d])m[d]=l++;
}
for(i=0;i<n;i++)
{
d=m[p[i].c];
w=p[i].h;
if(v[d].size())w+=v[d][v[d].size()-1].h;
t.h=w,t.d=p[i].d;
v[d].push_back(t);
}
len=0;
memset(h1,0,sizeof(h1));
memset(h2,0,sizeof(h2));
for(i=1;i<l;i++)
{
for(j=0;j<v[i].size();j++)
{
if(h1[j+1]<=v[i][j].h)
{
if(h1[j+1]==v[i][j].h)
{
a1[j+1].push_back(i);
continue;
}
if(a1[j+1].size())
{
h2[j+1]=h1[j+1];
a2[j+1]=a1[j+1][0];
}
h1[j+1]=v[i][j].h;
a1[j+1].clear();
a1[j+1].push_back(i);
}
else
{
if(h2[j+1]<v[i][j].h)
{
h2[j+1]=v[i][j].h;
a2[j+1]=i;
}
}
}
if(len<v[i].size())len=v[i].size();
}
Max=0;
for(i=1;i<=len;i++)
{
x1=h1[i];
for(j=i-1;j<i+2;j++)
{
if(j==0||j==len+1)continue;
x2=h1[j];
for(k=0;k<a1[i].size();k++)
{
y1=a1[i][k];
for(l=0;l<a1[j].size();l++)
{
y2=a1[j][l];
if(y1!=y2)break;
}
if(l!=a1[j].size())break;
}
if(k==a1[i].size())
{
x2=h2[j];
y2=a2[j];
}
if(x2==0)continue;
if(Max<x1+x2)
{
Max=x1+x2;
s=i+j;
i1=i,j1=j,y3=y1,y4=y2;
}
}
}
g.clear();
d=i1<j1?i1:j1;
if(i1<j1)swap(y3,y4);
for(i=0;i<d;i++)
{
g.push_back(v[y3][i].d);
g.push_back(v[y4][i].d);
}
if(i1!=j1)g.push_back(v[y3][i].d);
printf("%I64d\n%d\n",Max,s);
for(i=0;i<g.size();i++)
{
if(i)printf(" ");
printf("%d",g[i]);
}
printf("\n");
return 0;
}