Question D:
Idea: At first, we will choose whether the letter a is placed on the left or the right, and then we will choose the letter b to be placed on the left or the right, and the cycle continues until only one letter remains. Then the choice is 2 times each time, the total will be 2^k=n, then we can directly use the deep search to solve this problem, and first use the prefix and to preprocess the number of each letter in each interval .
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef long long ll;
const int MAXN=1e6+5;
const int M=1e6+5;
const double eps=1e-7;
const ll INF=0x3f3f3f3f;
char s[MAXN];
int sum[30][MAXN];
int ans;
void dfs(int l,int r,char c,int cnt)
{
if(l==r)
{
if(s[l]==c) ans=min(ans,cnt);
else ans=min(ans,cnt+1);
return;
}
dfs(l,(l+r)/2,c+1,cnt+r-(l+r)/2-sum[c-'a'+1][r]+sum[c-'a'+1][(l+r)/2]);
dfs((l+r)/2+1,r,c+1,cnt+(l+r)/2-l+1-sum[c-'a'+1][(l+r)/2]+sum[c-'a'+1][l-1]);
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
cin>>s+1;
for(int i=1;i<=26;i++)
{
sum[i][0]=0;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=26;j++)
{
sum[j][i]=sum[j][i-1];
}
int k=s[i]-'a'+1;
sum[k][i]++;
}
ans=1e9;
dfs(1,n,'a',0);
cout<<ans<<endl;
}
}
Question E:
Idea: At the beginning, save these edges first. When inputting edges, if they are directed edges, add the edges directly to the graph and record the in-degree of each point. Then we can use the queue-optimized topology to find the topological order. If a ring is found during the topological finding, NO will be output. Why is topological order required? Because the topological order of a point with a large in-degree is greater, our strategy is to point those undirected edges to the point with a large in-degree in the two points, so as to ensure that no ring is formed.
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
const double eps=1e-7;
const ll INF=0x3f3f3f3f;
int n,m;
int cnt=0;
int head[MAXN];
int pos[MAXN];
int in[MAXN];
struct EDGE
{
int to;
int next;
}e[MAXN];
struct node
{
int a,b;
int val;
}f[MAXN];
void add(int u,int v)
{
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
int toposort()
{
queue<int>q;
int res=n;
int tot=0;
for(int i=1;i<=n;i++)
{
if(in[i]==0) {
q.push(i);res--;pos[i]=++tot;}
}
while(!q.empty())
{
int u=q.front();
q.pop();
in[u]--;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
in[v]--;
if(in[v]==0) {
q.push(v);res--;pos[v]=++tot;}
}
}
if(res==0) return 1;
else return -1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
head[i]=-1;
pos[i]=0;
in[i]=0;
}
cnt=0;
int u,v,w;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&f[i].val,&f[i].a,&f[i].b);
if(f[i].val==1) {
add(f[i].a,f[i].b);in[f[i].b]++;}
}
int kk=toposort();
if(kk==-1)
{
printf("NO\n");
}
else
{
printf("YES\n");
for(int i=1;i<=m;i++)
{
if(f[i].val==1) printf("%d %d\n",f[i].a,f[i].b);
else
{
if(pos[f[i].a]<pos[f[i].b]) printf("%d %d\n",f[i].a,f[i].b);
else printf("%d %d\n",f[i].b,f[i].a);
}
}
}
}
}