SRM 606 DIV1 L1
先去重,再特判一个的情况,只是他题意不是非常明白,-1和-2注意区分
SRM 606 DIV1 L2
A Linear Time Majority Vote Algorithm算法模板题,实在想不出来# TCO2016 Round 3B DIV1 L1 RemoveCharacters
把两个字母的贡献独立,并预处理
最后
O
(
2
26
)
O(2^{26})
O(226)暴扫
code
#include<bits/stdc++.h>
const int P=1e9+7;
using namespace std;
class RemoveCharacters{
public:
int ma[100];
int s1[10000],s2[10000],top1,top2,flag,ans;
void dfs(int x,int m,int an){
if(x==26){
ans=max(ans,an);
return ;
}
if((ma[x]&m)==m)
if(ma[x]&(1<<x))
dfs(x+1,m|(1<<x),an+1);
dfs(x+1,m,an);
}
int minimalDistinct(string A, string B){
int n=A.size(),m=B.size();
for(int i='a';i<='z';i++)
for(int j='a';j<='z';j++){
top1=top2=0;
for(int k=1;k<=n;k++)
if(A[k-1]==i||A[k-1]==j)
s1[++top1]=A[k-1];
for(int k=1;k<=m;k++)
if(B[k-1]==i||B[k-1]==j)
s2[++top2]=B[k-1];
flag=top1==top2;
for(int k=1;k<=top1;k++)
if(s1[k]!=s2[k]) flag=0;
if(flag) ma[i-'a']|=(1<<(j-'a'));
}
//for(int i=0;i<26;i++) printf("%d ",ma[i]);
dfs(0,0,0);
return 26-ans;
}
};
SRM 615 Div1 L3: AlternativePiles
考虑R+1,G-1,只要
0
<
=
s
u
m
<
=
M
0<=sum<=M
0<=sum<=M的是合法的,因为只能分M组
然后考虑
O
(
n
∗
M
∗
B
)
O(n*M*B)
O(n∗M∗B)转移,B为去Blue的个数
然后
B
m
o
d
2
∗
M
B \mod 2*M
Bmod2∗M对答案不产生影响,然后复杂度为
O
(
n
∗
M
2
)
O(n*M^2)
O(n∗M2)
code
#include<bits/stdc++.h>
const int P=1e9+7;
using namespace std;
class AlternativePiles{
public:
int f[2][200][200];
void work(int x,int val,int m){
//printf("$%d %d %d\n",x,val,m);
for(int i=0;i<=m;i++){
if(i+val>m) continue;
if(i+val<0) continue;
for(int j=0;j<m*2;j++)
if(f[x^1][i][j]){
if(val) f[x][i+val][j]=(f[x^1][i][j]+f[x][i+val][j])%P;
else f[x][i][(j+1)%(m*2)]=(f[x][i][(j+1)%(m*2)]+f[x^1][i][j])%P;
}
}
/*
for(int i=0;i<=m;i++,printf("\n"))
for(int j=0;j<m*2;j++)
printf("%d ",f[x][i][j]);
*/
}
int count(string s,int m){
int n=s.size();
f[0][0][0]=1;
for(int i=1;i<=n;i++){
memset(f[i&1],0,sizeof(f[i&1]));
if(s[i-1]=='W'){
work(i&1,1,m);
work(i&1,-1,m);
work(i&1,0,m);
}
if(s[i-1]=='G') work(i&1,-1,m);
if(s[i-1]=='R') work(i&1,1,m);
if(s[i-1]=='B') work(i&1,0,m);
}
return f[n&1][0][n%(m*2)]%P;
}
};
SRM 602 DIV1 L1
暴力DP既可
code
#include<bits/stdc++.h>
using namespace std;
class TypoCoderDiv1{
public:
int ans,f[100][10000],bo[100][10000];
int getmax(vector <int> D, int X){
int n=D.size(),x;
if(n==1) return X+D[0]>=2200;
bo[0][X]=1;
f[0][X]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<2200;j++)
if(bo[i-1][j]){
x=j+D[i-1];
if(x<=2200) f[i][x]=max(f[i][x],f[i-1][j]),bo[i][x]=1;
x=max(j-D[i-1],0);
f[i][x]=max(f[i][x],f[i-1][j]);
bo[i][x]=1;
}
/*
for(int j=0;j<2200;j++)
if(bo[i][j])
printf("$%d ",j);
printf("\n");
*/
fflush(stdout);
if(i==1) continue;
for(int j=0;j<2200;j++)
if(bo[i-2][j]){
// printf("$$%d %d %d %d\n",j,i,D[i-2],D[i-1]);
if(j+D[i-2]<2200) continue;
if(j+D[i-2]-D[i-1]>=2200) continue;
// printf("$$$%d\n",j);
x=j+D[i-2]-D[i-1];
x=max(0,x);
f[i][x]=max(f[i][x],f[i-2][j]+2);
bo[i][x]=1;
}
/*
for(int j=0;j<2200;j++)
if(bo[i][j])
printf("%d ",j);
printf("\n");
*/
}
for(int i=0;i<2200;i++) ans=max(ans,f[n][i]);
for(int i=0;i<2200;i++)
if(bo[n-1][i]&&(D[n-1]+i>=2200))
ans=max(ans,f[n-1][i]+1);
return ans;
}
};
SRM 602 DIV1 L2
所有矩形小边为X,大边为Y,那
X
m
i
n
X_{min}
Xmin一定被取
那么枚举另一个X取哪一个
假设取
X
i
X_i
Xi这种情况下要考虑i~N*2前N大给
X
i
X_i
Xi还是后N大给
X
i
X_i
Xi,贪心把大的给
X
i
X_i
Xi是可以hack的,比如i~N*2的前K+1大中的最小值和次小值相同.
然后用堆维护,跑两边,分别维护两种情况
code
#include<bits/stdc++.h>
using namespace std;
long long X[600000],Y[600000],c[600000],bo[600000],minb[600000];
priority_queue<long long>q;
int mysort(int x,int y){
return X[x]<X[y];
}
int mysort2(int x,int y){
return Y[x]<Y[y];
}
class PilingRectsDiv1{
public:
long long ans;
int len;
long long getmax(int N, vector <int> XS, vector <int> YS, int XA, int XB, int XC, int YA, int YB, int YC){
for (int i = 0; i < XS.size(); i++) {
X[i] = XS[i];
Y[i] = YS[i];
}
for (int i = XS.size(); i < 2 * N; i++) {
X[i] = (X[i - 1] * XA + XB) % XC + 1;
Y[i] = (Y[i - 1] * YA + YB) % YC + 1;
}
for(int i=0;i<N*2;i++){
if(X[i]>Y[i]) swap(X[i],Y[i]);
c[i]=i;
}
sort(c,c+2*N,mysort);
for(int i=N*2-1;i>N;i--)
q.push(-Y[c[i]]);
minb[0]=Y[c[0]];
for(int i=1;i<=N-1;i++){
minb[i]=min(Y[c[i]],minb[i-1]);
}
minb[N]=1e9+7;
//printf("%lld",ans);
ans=0;
for(int i=N;i;i--){
q.push(-Y[c[i]]);
if(i!=N){
minb[i]=min(minb[i+1],-q.top());
q.pop();
}
ans=max(ans,1ll*(-q.top())*X[c[i]]+1ll*min(minb[i-1],minb[i])*X[c[0]]);
}
while(!q.empty()) q.pop();
minb[2*N]=Y[c[2*N-1]];
for(int i=N*2-1;i>=N;i--){
q.push(Y[c[i]]);
minb[i]=min(Y[c[i]],minb[i+1]);
}
minb[0]=Y[c[0]];
for(int i=1;i<=N-1;i++){
minb[i]=min(Y[c[i]],minb[i-1]);
}
for(int i=N-1;i;i--){
q.push(Y[c[i]]);
//printf("%lld\n",minb[i+1]);
minb[i]=min(minb[i+1],Y[c[i]]);
//printf("%lld %lld %lld %lld %lld\n",q.top(),minb[i-1],X[c[0]],minb[i],X[c[i]]);
ans=max(ans,1ll*(min(q.top(),minb[i-1]))*X[c[0]]+1ll*minb[i]*X[c[i]]);
q.pop();
}
return ans;
}
};
SRM 606 DIV1 L1
先去重,再特判一个的情况,只是他题意不是非常明白,-1和-2注意区分
#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],c[1000],s[1000],top,n,an;
int mysort(int x,int y){
return a[x]<a[y];
}
class EllysNumberGuessing{
public:
int getNumber(vector <int> A, vector <int> B){
n=A.size();
for(int i=1;i<=n;i++) a[i]=A[i-1];
for(int i=1;i<=n;i++) b[i]=B[i-1],c[i]=i;
sort(c+1,c+n+1,mysort);
for(int i=1;i<=n;i++){
if(a[c[i]]==a[c[i-1]]){
if(b[c[i]]!=b[c[i-1]]) return -2;
}else s[++top]=c[i];
}
int x=s[1],y=s[2];
if(top==1){
if(a[x]+b[x]<=1000000000&&a[x]-b[x]>=1) return -1;
if(a[x]+b[x]>1000000000&&a[x]-b[x]<1) return -2;
if(a[x]-b[x]>=1) return a[x]-b[x];
return a[x]+b[x];
}
c[1]=a[x]-b[x];
c[2]=a[x]+b[x];
c[3]=a[y]-b[y];
c[4]=a[y]+b[y];
sort(c+1,c+5);
for(int i=1;i<4;i++)
if(c[i]==c[i+1])
an=c[i];
if(an<1||an>1000000000) return -2;
for(int i=1;i<=n;i++)
if(a[i]+b[i]!=an&&a[i]-b[i]!=an)
return -2;
return an;
}
};
SRM 606 DIV1 L2
A Linear Time Majority Vote Algorithm算法模板题,实在想不出来
#include<bits/stdc++.h>
using namespace std;
class EllysPairing{
public:
int getMax(int M, vector<int> count, vector<int> first, vector<int> mult, vector<int> add){
int n=count.size(),ans,sum=0,x,sum2=0;
for(int i=0;i<n;i++){
x=first[i];
for(int j=1;j<=count[i];j++){
//printf("%d ",x);
if(sum==0) ans=x;
if(ans==x) sum++;
else sum--;
x=(1ll*x*mult[i]+add[i])&(M-1);
}
}
//printf("\n%d %d\n",ans,sum);
sum=0;sum2=0;
for(int i=0;i<n;i++){
x=first[i];
sum2=sum2+count[i];
for(int j=1;j<=count[i];j++){
if(ans==x) sum++;
x=(1ll*x*mult[i]+add[i])&(M-1);
}
}
if(sum>sum2/2)
sum=sum2-sum;
else sum=sum2/2;
return sum;
}
};