WY模拟赛2
模拟赛2
说实话,T1的题意理解属实搞心态。
T1
题意对我这种语文能力不强的蒟蒻确实造成巨大的冲击。
简述题中的排序
在满足祖辈关系的情况下,先考虑序号最小的,让序号最小的放在能放的最前面的位置,然后再考虑第二小的,以此类推。
解法
比较显然的部分是拓扑排序,入度为 $ 0 $ 的节点一定是问题的突破口。
尝试直接从祖宗开始推,发现一个节点所能被表示的深度不唯一,并不方便其在答案序列里位置的确定。于是一个非常合理的想法就出现在脑子里,倒着来试一下。就酱紫,反向存图,如果从小的位置编号开始赋值会发现并不好做,那就尝试从大的赋值。可以发现,在反向存图的情况下,入度为 $ 0 $ 的就是当前考虑赋值的节点,显然是这些节点中最大的被附上当前所剩空位置的最大编号,但同时这是一个动态的过程,当有新节点的入度为 $ 0 $ 时要及时加入,并维护节点最大值,一个优先队列解决。
#ifdef ONLINE_JUDGE
#else
#define Qiu_Cheng
#endif
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef longlong ll;
const int N=5e5+5,M=1e6+520,mod=1e9+7;
const int inf=INT_MAX,INF=1e9+7;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m,rd[N],ans[N];
vector<int>g[N];
fuck void solve()
{
n=read(),m=read();
for(int i=1;i<=n;i++)rd[i]=0,g[i].clear();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
rd[x]++;g[y].push_back(x);
}
priority_queue<int>q;
for(int i=1;i<=n;i++)if(!rd[i])q.push(i);
int cnt=n;
while(!q.empty())
{
int u=q.top();q.pop();
ans[cnt--]=u;
for(auto v:g[u])
{
rd[v]--;
if(!rd[v])q.push(v);
}
}
for(int i=1;i<=n;i++)write(ans[i]),cout<<" ";
cout<<"\n";
}
signed main()
{
#ifdef Qiu_Cheng
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
// int fuckccf=read();
int QwQ=read();
while(QwQ--)solve();
// solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
T2
一个分治的思想,一个四元组的性质可以拆解为两个同等性质的二元组,即 $ (i,j) $ 满足 $ A_{i} < A_{j} $ 。此时考虑枚举第一个二元组的第二个键值,答案即是第 $ j $ 个之前比其小的数记为 $ m1 $ ,第 $ j+1 $ 到 $ n $ 所能组成的二元组记为 $ m2 $ ,然后
该位置对答案的贡献就可以得出为 $ m1 \times m2 $ ,最后从 $ 1 $ 到 $ n $ 累加一下贡献即可。
维护 $ m1,m2 $ 的信息则选择用树状数组实现,先正序处理比 $ j $ 位置值小的数的个数得到 $ m1 $ ,然后倒序扫一遍维护出比 $ j $ 大的数,在做一遍后缀和则可以得到 $ m2 $ 。
#ifdef ONLINE_JUDGE
#else
#define Qiu_Cheng
#endif
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef longlong ll;
const int N=5e5+5,M=1e6+520,mod=1e9+7;
const int inf=INT_MAX,INF=1e9+7;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int tr[N];
#define lbit(x) x&(-x)
fuck void add(int x){while(x<N)tr[x]+=1,x+=lbit(x);}
fuck int sum(int x){int res=0;while(x){res+=tr[x];x-=lbit(x);}return res;}
int m1[N],m2[N],a[N],n;
fuck void solve()
{
n=read();
for(int i=1;i<=n;i++)a[i]=read();
memset(tr,0,sizeof(tr));for(int i=1;i<=n;i++){m1[i]=sum(a[i]);add(a[i]);}
memset(tr,0,sizeof(tr));for(int i=n;i>=1;i--){m2[i]=sum(n)-sum(a[i]-1);add(a[i]);}
int ans=0;m2[n+1]=0;
for(int i=n;i>=1;i--)m2[i]+=m2[i+1];
for(int i=1;i<=n;i++) ans+=(1ll*m1[i]*m2[i+1]);
write(ans);cout<<"\n";
}
signed main()
{
#ifdef Qiu_Cheng
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
// int fuckccf=read();
int QwQ=read();
while(QwQ--)solve();
// solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
T3
考虑一个状态压缩的思想,将 $ 26 $ 个字母出现次数的奇偶性压成一个 $ 26 $ 位的 $ 01 $ 串,具体地维护一个 $ mark $ 数组,下标为当前所压的转态,储存为状态出现的次数,定义如下规则:
- 对于当前出现次数为偶数的字母,则对应的位置为 $ 0 $ ;
- 对于当前出现次数为奇数的字母,则对应的位置为 $ 1 $ ;
先不考虑 ? ,每次按顺序扫一遍字符串,异或改变该位字符的奇偶性。这个时候就能发现一个非常有用的性质,如果该串的转态出现过,则对于前面出现的该状态,每个字符一定是又出现偶数次, $ because:奇+偶=奇,偶+偶=偶 $ 。这样我们在扫描字符串时,更新状态的同时直接处理答案即可。
再考虑 ? 的情况,以 ? 为断点,暴戾得将 ? 改为 $ a到z $ ,并将对应字母的位置取反,计算答案增量并累加上即可。
注意!!!
- 由于 $ mark $ 数组很大,所以只对使用过的清空,不然会
TLE。 - 千万要把
#define int long long关闭,不然会MLE。
#ifdef ONLINE_JUDGE
#else
#define Qiu_Cheng
#endif
#include <bits/stdc++.h>
#define i8 __int128
// #define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef longlong ll;
const int N=2e4+5,M=1e6+520,mod=1e9+7;
const int inf=INT_MAX,INF=1e9+7;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int mark[(1<<26)+10];
int sum[N];//前缀异或值
fuck void solve()
{
string s;cin>>s;s=' '+s;
int tot=0,pos=-1,ans=0;
sum[0]=0;mark[sum[0]]=1;
// cout<<"aaaaaaaaaaaaaaaaa"<<endl;
for(int i=1;i<s.size();i++)
{
if(s[i]=='?')
{
pos=i;ans+=mark[sum[tot]];
mark[sum[tot]]++;
continue;
}
tot++;
sum[tot]=sum[tot-1]^(1<<(s[i]-'a'));
ans+=mark[sum[tot]];
mark[sum[tot]]++;
}
for(int i=0;i<=tot;i++)mark[sum[i]]=0;
if(pos==-1){write(ans);cout<<"\n";return;}
sum[0]=0,mark[sum[0]]=1,tot=0;
for(int i=1;i<pos;i++)tot++,sum[tot]=sum[tot-1]^(1<<(s[i]-'a')),mark[sum[tot]]++;
for(int i='a';i<='z';i++)ans+=(mark[sum[tot]^(1<<(i-'a'))]);
for(int i=pos+1;i<s.size();i++)
{
tot++,sum[tot]=sum[tot-1]^(1<<(s[i]-'a'));
for(int j='a';j<='z';j++)ans+=(mark[sum[tot]^(1<<(j-'a'))]);
}
for(int i=0;i<=tot;i++)mark[sum[i]]=0;
write(ans),cout<<"\n";
}
signed main()
{
#ifdef Qiu_Cheng
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
// int fuckccf=read();
int QwQ=read();
while(QwQ--)solve();
// solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
T4
#ifdef ONLINE_JUDGE
#else
#define Qiu_Cheng
#endif
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef longlong ll;
const int N=1e6+5,M=1e6+520,mod=1e9+7;
const int inf=INT_MAX,INF=1e9+7;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int prime[N],is_prime[N]={1,1},tot=0;
fuck void xxs()
{
for(int i=1;i<=N;i++)is_prime[i]=0;
for(int i=2;i<=N;i++)
{
if(!is_prime[i])prime[++tot]=i;
for(int j=1;j<=tot&&i*prime[j]<=N;j++)
{
is_prime[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
fuck int gsc(int a,int b,int Mod)
{
a%=Mod,b%=Mod;
int res=0;
while(b)
{
if(b&1)res=(res+a+Mod)%Mod;
b>>=1;a=(a+a+Mod)%Mod;
}
return (res+Mod)%Mod;
}
fuck int ksm(int a,int b,int Mod)
{
int res=1;
while(b)
{
if(b&1)res=gsc(res,a,Mod);
b>>=1;a=gsc(a,a,Mod);
}
return (res+Mod)%Mod;
}
fuck int check(int a,int n,int x,int t)
{
int res=ksm(a,x,n),last=res;
for(int i=1;i<=t;i++)
{
res=gsc(res,res,n);
if((res==1)&&(last!=1)&&(last!=n-1))return 1;
last=res;
}
return res!=1;
}
fuck int Miller_Rabin(int n)
{
if((n<2))return 0;
if(n==2)return 1;
if((n&1)==0) return 0;
int x=n-1,t=0;
while((x&1)==0)x>>=1,t++;
for(int i=1;i<=20;i++)
{
int a=rand()%(n-1)+1;
if(check(a,n,x,t))return 0;
}
return 1;
}
fuck int sq(int n){int m=sqrt(n*1.0);return m*m==n||(m-1)*(m-1)==n||(m+1)*(m+1)==n;}
fuck int isyn(int n)
{
if(Miller_Rabin(n))return 1;
int ti=0;int m=n;
for(int i=1;i<=tot;i++)
{
if(m%prime[i]==0)
{
ti++;
if(ti>=2) return 0;
while(m%prime[i]==0)m/=prime[i];
}
if(m==1)return 1;
}
if(m!=n)return 0;
if(sq(n))return 1;
return 0;
}
fuck void solve()
{
int n;
while(n=read())
{
if(n==-1)break;
if(n==1){cout<<"0"<<"\n";continue;}
if(n!=4&&n%4==0){cout<<"1"<<"\n";continue;}
int m=n;
if(m%2==0)m/=2;
if(!isyn(m)){cout<<"1"<<"\n";}
else cout<<n-1<<"\n";
}
}
signed main()
{
#ifdef Qiu_Cheng
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
// int fuckccf=read();
xxs();
// for(int i=1;i<=tot;i++)cout<<prime[i]<<"\n";
// int QwQ=read();
// while(QwQ--)solve();
solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666

浙公网安备 33010602011771号