200716-省选模拟1
T1
题解
老套路了
维护左端nnn的个数L[i]L[i]L[i],右端iii的个数R[i]R[i]R[i]
ans=∑i=lr[s[i]==′o′](L[i]−L[l−1])(R[i]−R[r+1])ans=\sum_{i=l}^r[s[i]=='o'](L[i]-L[l-1])(R[i]-R[r+1])ans=∑i=lr[s[i]==′o′](L[i]−L[l−1])(R[i]−R[r+1])
拆开维护四个前缀和即可
代码
#include<bits/stdc++.h>
#define M 2000009
#define ull unsigned long long
using namespace std;
int read(){
int f=1,re=0;char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1,ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<1)+(re<<3)+ch-'0';
return re*f;
}
int n,m,tot;
ull maxn,ans1[M],ans2[M],ans3[M],ans4[M],L[M],R[M];
char s[M];
inline void init(){
int seed;
scanf("%d",&seed);
srand(seed);
}
inline void getQuery(int &l,int &r){
l=(long long)rand()*rand()%n+1,r=(long long)rand()*rand()%n+1;
if(l>r)std::swap(l,r);
}
int main(){
freopen("noi3.in","r",stdin);
//freopen("noi.out","w",stdout);
n=read(),m=read();
scanf("%s",s+1);init();
for(int i=1;i<=n;i++)
L[i]=L[i-1]+(s[i]=='n');
for(int i=n;i>=1;i--)
R[i]=R[i+1]+(s[i]=='i');
for(int i=1;i<=n;i++){
ans1[i]=ans1[i-1];
ans2[i]=ans2[i-1];
ans3[i]=ans3[i-1];
ans4[i]=ans4[i-1];
if(s[i]=='o'){
ans1[i]+=L[i];
ans2[i]+=L[i]*R[i];
ans3[i]++;
ans4[i]+=R[i];
}
}
for(int i=1;i<=m;i++){
int l,r;ull ans=0;
getQuery(l,r);
ans=-(R[r+1]*(ans1[r]-ans1[l-1])-(ans2[r]-ans2[l-1])-R[r+1]*L[l-1]*(ans3[r]-ans3[l-1])+(ans4[r]-ans4[l-1])*L[l-1]);
maxn=maxn^ans;
}cout<<maxn<<endl;
return 0;
}
T2
题解
1,50分暴力:
我们发现两条路径显示是相反的,那么对n<=11n<=11n<=11的情况可以考虑从小到大枚举,拓扑判断即可
2,100分正解:
代码
#include<bits/stdc++.h>
#define M 200009
using namespace std;
int dfn[M],cnt,low[M],n,m,num,ans[M];
bool cut[M],vis[M],bj[M];
int nxt[M],to[M],first[M],tot;
int read(){
int f=1,re=0;char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1,ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<1)+(re<<3)+ch-'0';
return re*f;
}
void add(int x,int y){
nxt[++tot]=first[x];
first[x]=tot;
to[tot]=y;
}
void tarjan(int u,int fa){
cut[u]=0;
dfn[u]=low[u]=++num;
for(int i=first[u];i;i=nxt[i]){
int v=to[i];
if(v!=fa&&!bj[v]){
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]) cut[u]=1;
}else low[u]=min(low[u],dfn[v]);
}
}
}
void addpoint(int u){
bj[u]=1;
for(int i=first[u];i;i=nxt[i]) vis[to[i]]=1;
}
int main(){
freopen("messenger3.in","r",stdin);
//freopen("messenger.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
add(x,y),add(y,x);
}tarjan(1,0);
for(int i=2;i<=n;i++) if(cut[i]||!dfn[i]) puts("-1"),exit(0);
addpoint(ans[1]=1),bj[1]=0;
for(int i=2;i<=n;i++){
memset(dfn,0,sizeof(dfn));
num=0;tarjan(1,0);
for(int j=2;j<=n;j++){
if(!bj[j]&&vis[j]&&!cut[j]){
addpoint(ans[i]=j);
break;
}
}
}for(int i=2;i<=n;i++)printf("%d ",ans[i]);
printf("\n");
for(int i=n;i>=2;i--)printf("%d ",ans[i]);
return 0;
}
T3
咕咕咕~