这个题不知道欠了有多久....到现在还没写....
应该是又一个slot
upd:补完了
先贴一个std
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
void Rd(int &res){
res=0;static char p;
while(p=getchar(),p<'0');
do{
res=(res*10)+(p^48);
}while(p=getchar(),p>='0');
}
void Ps(int x){
static int stk[64],sz;sz=0;
while(x)stk[sz++]=x%10,x/=10;
if(sz==0)putchar('0');
else while(sz--)putchar(stk[sz]^48);
putchar('\n');
}
const unsigned long long mx=-1;
const int M=50005;
unsigned long long bin[64],sbin[64];
int pcnt[(1<<16)];
int cntp(unsigned long long a){
return pcnt[a&65535]+pcnt[(a>>16)&65535]+pcnt[(a>>32)&65535]+pcnt[(a>>48)&65535];
}
struct BITSET{
unsigned long long val[788];
int n,sz;
void reset1(int n_,int ned){
n=n_,sz=n_>>6;
int up=ned>>6;
for(int i=0;i<up;i++)val[i]=mx;
val[up]=sbin[ned&63];
for(int i=up+1;i<=sz;i++)val[i]=0;
}
void reset0(int n_){
n=n_,sz=n_>>6;
for(int i=0;i<=sz;i++)val[i]=0;
}
void operator &=(const BITSET &a){
for(int i=0;i<=sz;i++)val[i]&=a.val[i];
}
void operator |=(const BITSET &a){
for(int i=0;i<=sz;i++)val[i]|=a.val[i];
}
void operator ^=(const BITSET &a){
for(int i=0;i<=sz;i++)val[i]^=a.val[i];
}
void And(const BITSET &a,BITSET &b)const{
b.n=n,b.sz=sz;
for(int i=0;i<=sz;i++)b.val[i]=val[i]&a.val[i];
}
void Or(const BITSET &a,BITSET &b)const{
b.n=n,b.sz=sz;
for(int i=0;i<=sz;i++)b.val[i]=val[i]|a.val[i];
}
void Xor(const BITSET &a,BITSET &b)const{
b.n=n,b.sz=sz;
for(int i=0;i<=sz;i++)b.val[i]=val[i]^a.val[i];
}
void shf(){
for(int i=sz;i>0;i--)val[i]=val[i]<<1|(val[i-1]>>63);
val[0]<<=1;
}
int CNT(){
int re=0;
for(int i=0;i<=sz;i++)re+=cntp(val[i]);
return re;
}
void set(int x){
val[x>>6]|=bin[x&63];
}
}g[15],h[15],msk,ll,rr,f0,f1,f2,f3;
int n,m;
char S[M];
void get_msk(int l,int r){
if(l)ll.reset1(n,l-1);
else ll.reset0(n);
rr.reset1(n,r);
ll.Xor(rr,msk);
}
void solve(){
Rd(n),Rd(m);
scanf("%s",S+1);
for(int i=0;i<=9;i++)g[i].reset0(n);
for(int i=1;i<=n;i++)g[S[i]-'0'].set(i);
for(int i=1,l,r,len,v;i<=m;i++){
static char A[M];
scanf("%s",A);
if(A[0]=='?'){
Rd(l),Rd(r),scanf("%s",A+1),len=strlen(A+1);
if(r-l+1<len){
puts("0");
continue;
}
if(len<=3){
Ps(r-l+1-len+1);
continue;
}
get_msk(l-1,r-len);
f0=msk;
f1.reset0(n),f2.reset0(n),f3.reset0(n);
for(int j=1;j<=len;j++){
f0.shf(),f1.shf(),f2.shf(),f3.shf();
f3&=g[A[j]-'0'],f3|=f2;
f2&=g[A[j]-'0'],f2|=f1;
f1&=g[A[j]-'0'],f1|=f0;
f0&=g[A[j]-'0'];
}
Ps(f3.CNT());
}else {
Rd(l),Rd(r),Rd(v);
get_msk(l,r);
for(int j=0;j<=9;j++)g[j].And(msk,h[j]),g[j]^=h[j];
for(int j=0;j<=9;j++)g[(j+v)%10]|=h[j];
}
}
}
int main(){
for(int i=0;i<64;i++)bin[i]=(1uLL<<i);
sbin[0]=1;
for(int i=1;i<64;i++)sbin[i]=sbin[i-1]|bin[i];
for(int i=1;i<65536;i++)pcnt[i]=pcnt[i>>1]+(i&1);
int cas;Rd(cas);
while(cas--)solve();
return 0;
}
PS:感谢高铁。zx学长也说高铁上写代码甚至可以比平常效果更好!
【maxflow+augment】
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdlib>
#define N 101010
#define mo 200000
#define inf 1000000000
using namespace std;
int ans,edgenum,n,m,K,du[N],h[220],col=0,tot,jl[220][220];
int vet[N],head[220],jie[N],q[N*2],ajl[220][220];
int pri[N],vis[N],match[N],S,T,ee[220][220];
int mat[220][220],aa[N],color[300][300];
int cmp(int a,int b){
return du[a]<du[b];
}
struct node {int id,c;}a[N];
void add(int u,int v,int w)
{
edgenum++;vet[edgenum]=v;jie[edgenum]=head[u];head[u]=edgenum;pri[edgenum]=w;
edgenum++;vet[edgenum]=u;jie[edgenum]=head[v];head[v]=edgenum;pri[edgenum]=0;
}
void addnew(int u,int v){
printf("===%d %d\n",u,v);
edgenum++;vet[edgenum]=v;jie[edgenum]=head[u];head[u]=edgenum;
}
int dfs(int u,int aug)
{
if(u==T)return aug;
int used=0,w,e=head[u],ee;
while(e>0)
{
int v=vet[e];
if(h[v]==h[u]+1)
if(pri[e]>0)
{
if(e%2==1)ee=e+1;else ee=e-1;
w=dfs(v,min(aug-used,pri[e]));
used+=w;pri[e]-=w;pri[ee]+=w;
if(used==aug)return used;
}
e=jie[e];
}
if(used<=0)h[u]=-1;return used;
}
bool bfs()
{
for(int i=0;i<=T;i++)h[i]=-1;
int tou=1,tail=1;q[1]=S;h[S]=0;
while(tou<=tail)
{
int u=q[tou%200000],e=head[u];
while(e>0)
{
int v=vet[e];
if(h[v]<0)if(pri[e]>0)
{
h[v]=h[u]+1;tail++;q[tail%200000]=v;
}
e=jie[e];
}
tou++;
}
return (h[T]!=-1);
}
int dinic()
{
int sum=0;
while(bfs())
{
sum+=dfs(S,inf);
}
return sum;
}
int line(int u){
int e=head[u];
while(e>0){
int i=vet[e];
if(jl[u][i] && vis[i]==0){
vis[i]=1;
if(match[i]==0 || line(match[i])){
match[u]=i;
match[i]=u;
return 1;
}
}
e=jie[e];
}
return 0;
}
int maxmatch(){
int sum=0;
memset(match,0,sizeof(match));
for(int i=1;i<=n/2;i++){
if(match[i]==0){
memset(vis,0,sizeof(vis));
sum+=line(i);
}
}
return sum;
}
void augment(int v, int c1, int c2) {
if (color[v][c1] == 0){
color[v][c2] = 0;
return;
}
else {
int w = color[v][c1];
augment(w, c2, c1);
color[v][c2] = w;
color[w][c2] = v;
}
}
pair<int,int> find(int a,int b){
int af = 0, bf = 0;
for (int c = 1; c <= K; c++) {
if (color[a][c] == 0 && color[b][c] == 0) {
return make_pair(c, c);
}
if (color[a][c] == 0) af = c;
if (color[b][c] == 0) bf = c;
}
return make_pair(af, bf);
}
int main(){
scanf("%d%d%d",&n,&m,&K);
T=n+1;
for(int i=1;i<=n/2;i++)add(S,i,K);
for(int i=n/2+1;i<=n;i++)add(i,T,K);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v,1);
ee[v][u]=edgenum;
ajl[u][v]=i;
}
ans=dinic();
printf("%d\n",ans);
edgenum=0;
memset(head,0,sizeof(head));
for(int i=1;i<=n/2;i++){
for(int j=n/2+1;j<=n;j++)if(pri[ee[j][i]]){
pair<int,int> f=find(i,j);
if(f.first==f.second){
color[i][f.first]=j;
color[j][f.first]=i;
}else{
augment(i,f.second,f.first);
color[i][f.second]=j;
color[j][f.second]=i;
}
}
}
for(int i=1;i<=n/2;i++){
for(int j=1;j<=K;j++)if(color[i][j]>0){
printf("%d %d\n",ajl[i][color[i][j]],j);
}
}
return 0;
}
/*
8 9 2
1 6
1 7
2 7
2 8
3 5
3 8
4 5
4 6
4 8
8 7 2
2 6
3 7
4 8
1 6
2 7
3 8
4 7
*/