http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=338
B题 我用的是二分 + 树状数组 ,x&(-x) 写成了 x&(-x)弄了半天
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=100010;
#define lowbit(x) x&(-x)
ll tab[maxn],num[maxn],op[maxn];
int Max,tot;
char ord[maxn][10];
int cnt[maxn];
int bin1(ll key)
{
int l=1,r=Max,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(tab[mid]==key) return mid;
else if(tab[mid] > key) r=mid-1;
else l=mid+1;
}
}
void insert(int pos,int d)
{
for(int i=pos;i<=Max;i+=lowbit(i))
num[i]+=d;
}
int query(int pos)
{
int sum=0;
for(int i=pos;i>0;i-=lowbit(i))
sum+=num[i];
return sum;
}
long long bin2(int s)
{
int l=1,r=Max,mid,ans=Max;
while(l<=r)
{
mid=(l+r)>>1;
int tmp=query(mid);
if(tmp>=s)
{
ans=mid,r=mid-1;
}
else l=mid+1;
}
return tab[ans];
}
int main()
{
int ca,n,k;
scanf("%d",&ca);
while(ca--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s %lld",ord[i],&op[i]);
tab[i+1]=op[i];
}
sort(tab+1,tab+n+1);
Max=1;
for(int i=2;i<=n;i++)
if(tab[i]!=tab[i-1]) tab[++Max]=tab[i];
memset(num,0,sizeof(num));
memset(cnt,0,sizeof(cnt));
tot=0;
//cout<< Max <<endl;
for(int i=0;i<n;i++)
{
int pos=bin1(op[i]);
//cout<<"bug" << pos <<" "<< query(pos) <<endl;
if(ord[i][0]=='a')
{
tot++;
insert(pos,1);
cnt[pos]++;
if(tot%2)
{
printf("%lld\n",bin2(tot/2+1));
}
else
{
long long a=bin2(tot/2),b=bin2(tot/2+1);
//cout<< a <<" "<< b<< " " << query(3)<<endl;
if(((a+b)%2+2)%2==0) printf("%lld\n",(a+b)/2);
else printf("%.1lf\n",(a+b)*1.0/2);
}
}
else
{
int now=query(pos),pre=query(pos-1);
//cout<< pre <<" "<<now<<endl;
if(cnt[pos]==0) puts("Wrong!");
else
{
tot--;
insert(pos,-1);
cnt[pos]--;
if(tot==0) puts("Empty!");
else
{
if(tot%2)
{
printf("%lld\n",bin2(tot/2+1));
}
else
{
long long a=bin2(tot/2),b=bin2(tot/2+1);
if(((a+b)%2+2)%2==0) printf("%lld\n",(a+b)/2);
else printf("%.1lf\n",(a+b)*1.0/2);
}
}
}
}
}
}
return 0;
}
/*
8
add 1
add 1
add 1
add 3
add 3
add 4
add 2
remove 2
*/
J题 这个题很简单 ,很常见的状态压缩dp,d[state][node] 表示遍历了state 状态 到达node 节点所花费的最短时间
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int INF=100000000;
int n,m,T;
int value[10],start,end,dist[10][10];
int ans;
int dp[1024][11];
void floyed()
{
/* for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
dist[i][j]=map[i][j];*/
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
{
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
}
int main()
{
int a,b,c;
while(scanf("%d%d%d",&n,&m,&T)==3)
{
scanf("%d%d",&start,&end);
for(int i=0;i<n;i++) scanf("%d",&value[i]);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
dist[i][j]=INF;
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&a,&b,&c);
if(dist[a][b]>c) dist[a][b]=dist[b][a]=c;
}
for(int i=0;i<n;i++) dist[i][i]=0;
floyed();
ans=0;
for(int j=0;j<(1<<n);j++)
for(int i=0;i<n;i++)
dp[j][i]=INF;
dp[1<<start][start]=0;
int limit=1<<n;
for(int i=0;i<limit;i++)
for(int j=0;j<n;j++)
if(dp[i][j]<=T)
{
for(int k=0;k<n;k++)
dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+dist[j][k]);
}
//int ans
for(int i=0;i<limit;i++)
if(dp[i][end]<=T)
{
int sum=0;
for(int j=0;j<n;j++)
if(i&(1<<j)) sum+=value[j];
if(ans<sum) ans=sum;
}
printf("%d\n",ans);
}
return 0;
}
最蛋疼的就是K了,浪费了我这么多时间,还没有做出来,思路我想出来了,就是把题意理解的错误,0 ≤ s < 2^63, 2 ≤ k ≤ 62 ,这个s如果用十进制的组多2^63,我还以为long long 也会超,都没敢再做;
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ll;
const ll inf=1LL<<63;
int a[110];
vector<pair<int,int> > e[110];
ll sum[110];
int main()
{
ll s;
char str[110];
int k;
for(int i=2;i<=62;i++){
if(a[i]==0){
e[i].push_back(make_pair(i,1));
for(int j=i*2;j<=62;j+=i){
a[j]=1;
int t=j,cnt=0;
while(t%i==0){
t/=i;
cnt++;
}
e[j].push_back(make_pair(i,cnt));
}
}
}
//for(int i=0;i<e[62].size();i++)
// cout<< e[62][i].first<<" "<<e[62][i].second<<endl;
while(cin>>str>>k)
{
int len=strlen(str);
s=0;int p;
for(int i=0;i<len;i++){
if('0'<=str[i]&&str[i]<='9')
p=str[i]-'0';
else if('A'<=str[i]&&str[i]<='Z')
p=str[i]-'A'+10;
else if('a'<=str[i]&&str[i]<='z')
p=str[i]-'a'+36;
s=s*k+p;
}
//cout<< s <<endl;
ll ans=inf;
for(int i=0;i<e[k].size();i++)
{
int p=e[k][i].first;
ll N=s,cnt=0;
while(N)
{
cnt+=N/p;
N/=p;
}
ans=min(ans,cnt/e[k][i].second);
}
cout<< ans <<endl;
}
return 0;
}
D题 还有没有ac,不知道怎么错了,先贴出了以后再看;
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=510;
int n,m;
double matrix[maxn][maxn],sum1[maxn][maxn],sum2[maxn][maxn];
double heig[maxn][maxn],heigh[maxn][maxn];
int que[maxn];
int main()
{
int Q,a,b,ca=1;
while(scanf("%d %d",&n,&m)==2)
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
scanf("%lf",&matrix[i][j]);
sum1[i][j]=sum2[i][j]=0;
}
for(int i=0;i<n;i++)
{
double tot=0;
for(int j=0;j<m;j++)
{
tot+=matrix[i][j];
sum1[i][j]= (i==0?0:sum1[i-1][j])+tot;
}
}
for(int i=0;i<n;i++)
{
double tot=0;
for(int j=0;j<m;j++)
{
tot+=matrix[i][j]*matrix[i][j];
sum2[i][j]=(i==0?0:sum2[i-1][j])+tot;
}
}
// cout<<sum1[1][1]<<" "<<sum2[2][0]<<endl;
printf("Case %d:\n",ca++);
scanf("%d",&Q);
double ans=99999999;
int sx,sy;
while(Q--)
{
scanf("%d %d",&a,&b);
ans=99999999;
for(int i=0;i<n;i++)
{
int l=0,r=-1;
for(int j=0;j<m;j++)
{
while(l<=r&&matrix[i][que[r]] < matrix[i][j]) r--;
que[++r]=j;
if(j>=b-1) heig[i][j-b+1]=matrix[i][que[l]];
if(r-l+1>=b) l++;
}
}
//cout<< heig[1][1] <<endl;
for(int i=0;i<m;i++)
{
int l=0,r=-1;
for(int j=0;j<n;j++)
{
while(l<=r&&heig[que[r]][i] < heig[j][i]) r--;
que[++r]=j;
if(j>=a-1) heigh[j-a+1][i]=heig[que[l]][i];
if(r-l+1>=a) l++;
}
}
//cout<< heigh[2][3] <<endl;
for(int i=0;i<=n-a;i++)
for(int j=0;j<=m-b;j++)
{
double tmp1=(sum2[i+a-1][j+b-1]- (j==0?0:sum2[i+a-1][j-1]) - (i==0?0:sum2[i-1][j+b-1]) + ((i==0||j==0)?0:sum2[i-1][j-1]) -heigh[i][j]*heigh[i][j])/(a*b-1);
double tmp2=(sum1[i+a-1][j+b-1]- (j==0?0:sum1[i+a-1][j-1]) - (i==0?0:sum1[i-1][j+b-1]) + ((i==0||j==0)?0:sum1[i-1][j-1])-heigh[i][j])/(a*b-1);
tmp2*=tmp2;
if(tmp1-tmp2 < ans)
{
ans=tmp1-tmp2;
sx=i,sy=j;
}
else if(tmp1-tmp2 == ans&&sx>i)
{
// ans=tmp1-tmp2;
sx=i,sy=j;
}
else if(tmp1-tmp2 == ans&&sx==i&&sy>j)
{
//ans=tmp1-tmp2;
sx=i,sy=j;
}
}
printf("(%d, %d), %.2lf\n",sx+1,sy+1,ans);
}
}
return 0;
}
D 题终于知道错在哪里了,一个傻逼错误wa的我半死不活了,bug半天也没看出来,跟ac程序对拍才发现
if(r-l+1>=b) l++;
写错了,看来模版题还是要多敲呀多记呀