AB傻逼题
A枚举子集
B维护前缀和
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+100;
int n,m,k;
char s[2001][2001];
int f[3000]={};
int bin[15];
int main(){
// freopen("a.in","r",stdin);
bin[0]=1;
for(int i=1;i<=12;i++)bin[i]=bin[i-1]*2;
int Cas,Id=0;
scanf("%d",&Cas);
while(Cas--){
int ans=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%s",s[i]);
}
int Mx=(1<<m)-1;
for(int i=1;i<=Mx;i++){
int ret=0;
memset(f,0,sizeof(f));
for(int j=1;j<=n;j++){
int sum=0;
for(int k=0;k<m;k++){
if(!(i&(1<<k)))continue;
if(s[j][k]=='A')sum+=bin[k];
}
// cout<<ret<<" "<<f[sum]<<'\n';
ret+=(j-f[sum]-1);
f[sum]++;
}
// cout<<ret<<'\n';
if(ret>=k)ans++;
}
cout<<"Case #"<<(++Id)<<": "<<ans<<'\n';
}
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1000;
int n,Q,T;
char s[N];
int A[N][26];
int main(){
int Cas,Id=0;
scanf("%d",&Cas);
while(Cas--){
int n,q;
scanf("%d%d",&n,&q);
scanf("%s",s+1);
memset(A,0,sizeof(A));
for(int i=1;i<=n;i++){
A[i][s[i]-'A']=1;
}
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++){
A[i][j]=A[i-1][j]+A[i][j];
}
}
cout<<"Case #"<<(++Id)<<":"<<'\n';
while(q--){
int l,r;
scanf("%d%d",&l,&r);
for(int i=0;i<26;i++){
if(A[r][i]-A[l-1][i]){
cout<<(A[r][i]-A[l-1][i])<<'\n';
break;
}
}
}
}
}
C有点难啊:
考虑费用流模型:S-X流 INF,费1 Y-T 流INF 费1 中间正常连边
TLE。
所以KM
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 2e2 + 10, inf = 0x3f3f3f3f;
typedef long long ll;
int T, n, w[maxn][maxn], dx[maxn], dy[maxn], slack[maxn], visx[maxn], visy[maxn], l[maxn], r[maxn], pre[maxn];
void bfs(int u) {
queue<int> Q; Q.push(u);
visx[u] = 1;
while (1) {
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int y = 1; y <= n; y++) {
int dif = dx[x] + dy[y] - w[x][y];
if (!visy[y] && dif <= slack[y]) {
pre[y] = x;
if (!dif) {
if (!l[y]) {
for (; y; l[y] = pre[y], swap(y, r[pre[y]]));
return;
} else {
visx[l[y]] = visy[y] = 1;
Q.push(l[y]);
}
} else {
slack[y] = dif;
}
}
}
}
int cmp = inf;
for (int i = 1; i <= n; i++) {
if (!visy[i] && slack[i] <= cmp) {
u = i, cmp = slack[i];
}
}
for (int i = 1; i <= n; i++) {
if (visx[i]) dx[i] -= cmp;
if (visy[i]) dy[i] += cmp;
else slack[i] -= cmp;
}
if (!l[u]) {
for (; u; l[u] = pre[u], swap(u, r[pre[u]]));
return;
} else {
visx[l[u]] = visy[u] = 1;
Q.push(l[u]);
}
}
}
void km() {
for (int i = 1; i <= n; i++) {
memset(visx, 0, sizeof visx);
memset(visy, 0, sizeof visy);
memset(slack, 0x3f, sizeof slack);
bfs(i);
}
}
void Pre(){
memset(dx, 0, sizeof dx);
memset(dy, 0, sizeof dy);
memset(l, 0, sizeof l);
memset(r, 0, sizeof r);
memset(pre, 0, sizeof pre);
}
int main() {
// freopen("c.in","r",stdin);
int Id=0;
scanf("%d", &T);
while(T--){
Pre();
cout<<"Case #"<<++Id<<": ";
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &w[i][j]), w[i][j] = -w[i][j];
dx[i] = max(dx[i], w[i][j]);
}
}
km();
ll ans = 0;
for (int i = 1; i <= n; i++) ans += -dx[i] - dy[i];
cout<<ans<<'\n';
}
return 0;
}
E题因为随机化,直接暴力就好了
#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long
#define pb push_back
#define inf 0x3f3f3f3f
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int mod=1e9+7;
int a[10010],N,M;
int C[10010],ans[10010],f[2][10010];
struct BIT{
inline int lowbit(int x){
return x&(-x);
};
inline void update(int x,int val){
while(x<=N){
C[x]+=val;
C[x]%=mod;
x+=lowbit(x);
}
}
inline int Query(int x){
int ret=0;
while(x){
ret=(ret+C[x])%mod;
x-=lowbit(x);
}
return ret;
}
}T;
int n,m;
INT main(){
// freopen("e.in","r",stdin);
int Cas,Id=0;
read(Cas);
while(Cas--){
read(n);
N=n;
for(int i=1;i<=n;++i) read(a[i]),f[0][i]=1;
ans[1]=n;
int cur=1;
for(int len=2;len<=n;++len){
ans[len]=0;
if(ans[len-1]==0) continue;
for(int i=1;i<=n;++i){
int tmp=T.Query(a[i]-1);
ans[len]+=tmp;
T.update(a[i],f[cur^1][i]);
f[cur][i]=tmp;
}
for(int i=1;i<=n;++i)C[i]=0;
cur^=1;
}
cout<<"Case #"<<++Id<<": ";
for(int i=1;i<=n-1;++i) cout<<ans[i]%mod<<" ";
cout<<ans[n];
cout<<'\n';
}
return 0;
}
BestCoder Contest System 2.0
F题两颗最小生成树暴力加边,打擂台输出答案
#include<bits/stdc++.h>
using namespace std;
const int N=301;
const int INF=1e9+7;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
struct Front_star{
int u,v,w,c,use,nxt;
}e[N*2];
int cnt=0;
int first[N]={};
void add(int u,int v,int w,int c){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].c=c;
e[cnt].nxt=first[u];
first[u]=cnt;
}
bool cmp(Front_star A,Front_star B){
return A.w<B.w;
}
int fa[N]={};
int ans[N]={};
int n,m;
inline int getfa(int x){
if(fa[x]==x)return x;
else return fa[x]=getfa(fa[x]);
}
inline void Union(int x,int y){
int dx=getfa(x);
int dy=getfa(y);
fa[dx]=dy;
}
void Kruskal(int no){
int ecnt=0;
int sum=0;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
e[i].use=0;
if(e[i].c==no)continue;
int u=e[i].u;
int v=e[i].v;
if(getfa(u)!=getfa(v)){
Union(u,v);
ecnt++;
sum+=e[i].w;
e[i].use=1;
}
}
// cout<<ecnt<<"--"<<'\n';
if(ecnt<n-1)return;
if(ans[n-1]==-1)ans[n-1]=sum;
else ans[n-1]=min(ans[n-1],sum);
int l=1;
// cout<<sum<<'\n';
for(int i=1;i<=m;i++){
if(e[i].use)continue;
sum+=e[i].w;
ecnt++;
// cout<<ecnt<<" "<<sum<<'\n';
if(ans[ecnt]==-1)ans[ecnt]=sum;
else ans[ecnt]=min(ans[ecnt],sum);
}
// cout<<'\n';
}
void Pre(){
memset(first,0,sizeof(first));
cnt=0;
}
int main(){
// freopen("f.in","r",stdin);
int Cas,Id=0;
read(Cas);
while(Cas--){
cout<<"Case #"<<++Id<<":"<<'\n';
Pre();
read(n);
read(m);
for(int i=1;i<=m;i++){
int u,v,w,c;
char ch[3];
read(u);
read(v);
read(w);
scanf("%s",ch);
// cout<<u<<" "<<v<<" "<<w<<" "<<ch<<'\n';
if(ch[0]=='R'){
c=1;
}
if(ch[0]=='B'){
c=2;
}
if(ch[0]=='G'){
c=3;
}
add(u,v,w,c);
}
sort(e+1,e+1+cnt,cmp);
for(int i=1;i<=m;i++)ans[i]=-1;
Kruskal(1);
Kruskal(2);
for(int i=1;i<=m;i++){
cout<<ans[i]<<'\n';
}
}
}