2019浙江省赛补题 +manacha算法

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019浙江省赛补题 +manacha算法相关的知识,希望对你有一定的参考价值。

# J - Welcome Party
建图+并查集+优先队列
本题的难点在于输出顺序的处理
优先队列:将每一层结点从小到大出队列。

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int n,m,f[maxn],cnt,k,p[maxn],head[maxn];
bool vis[maxn];
struct edge

    int to,nxt;
e[maxn<<1];
void add(int from,int to)

    e[++cnt].to=to;
    e[cnt].nxt=head[from];
    head[from]=cnt;

int r_find(int x)
    if (f[x]!=x)
        f[x]=r_find(f[x]);
    return f[x];

void update(int u,int v)

    int fx=r_find(u),fy=r_find(v);
    if(fx==fy)
        return;
    if(fx>fy) swap(fx,fy);
    f[fy]=fx;

void bfs(int u)

    priority_queue<int,vector<int>,greater<int> >q;
    q.push(u);
    while(!q.empty())
    
        int u=q.top();q.pop();
        if(vis[u])
            continue;
        vis[u]=1;p[++k]=u;
        for(int i=head[u];~i;i=e[i].nxt)
        
            int v=e[i].to;
            if(!vis[v])
            
                q.push(v);
            
        
    

int main()

    int t;cin>>t;
    while(t--)
    
        cin>>n>>m;
        for(int i=0;i<=n;i++)
            f[i]=i,vis[i]=0,head[i]=-1;
        cnt=0;
        for(int i=1;i<=m;i++)
        
            int u,v;scanf("%d%d",&u,&v);
            add(u,v),add(v,u);update(u,v);
        
        int ans=0;k=0;
        for(int i=1;i<=n;i++)
        
            if(r_find(i)==i)
            
                ans++;add(0,i);
            
        
        k=0;bfs(0);
        printf("%d\\n",ans);
        for(int i=2;i<=k-1;i++)
            printf("%d ",p[i]);
        printf("%d\\n",p[k]);
    
    return 0;

# B - Element Swapping
数学模拟 有机会

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+5;
int n,x,y,sum1,sum2,a[maxn];

signed main()

    int t;cin>>t;
    while(t--)
    
        map<int,int>mp;int ans=0;
        scanf("%lld%lld%lld",&n,&x,&y); //x,y换前
        sum1=0,sum2=0; //换后
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]),sum1+=i*a[i],sum2+=i*a[i]*a[i],mp[a[i]]++;
        if(sum1==x&&y==sum2)
        
            for(int i=1;i<=n;i++)
            
                if(mp[a[i]])
                
                    ans+=(mp[a[i]]*(mp[a[i]]-1))/2;
                    mp[a[i]]=0;
                
            
            cout<<ans<<endl;
        
        else if(sum1!=x&&sum2!=y&&((y-sum2)%(x-sum1))==0)
        
            int tmp=(y-sum2)/(x-sum1);
            for(int i=1;i<=n;i++)
            
                int b=tmp-a[i];
                if(a[i]!=b&&(x-sum1+i*(a[i]-b))%(a[i]-b)==0)
                
                    int p=(x-sum1+i*(a[i]-b))/(a[i]-b);
                    if(a[p]==b&&p>=1&&p<=n)
                        ans++;
                
            
            cout<<ans/2<<endl;
        
        else
            cout<<0<<endl;
        mp.clear();
    
    return 0;


Strings in the Pocket
马拉车算法,讲的非常清晰,yyds
https://www.bilibili.com/video/BV1rE411x78x?spm_id_from=333.337.search-card.all.click
模板:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=5e7+5;
string s;
int p[maxn];
int manacher()

    string ss="@#";
    for(int i=0;i<s.length();i++)
        ss+=s[i],ss+='#';
    int len=ss.length();
    int mx=0; //当前延伸最远的回文子串,下标的后一位
    int id=0,ans=0; //对称中心
    for (int i=1;i<len;i++)
    
        if(i<mx)  p[i]=min(p[2*id-i],mx-i);
        else
            p[i]=1;
        while(ss[i+p[i]]==ss[i-p[i]]) p[i]++;
        if(p[i]+i>mx)
            mx=p[i]+i,id=i;
        ans=max(ans,p[i]-1);
    
    return ans;


signed main()

    cin>>s;
    cout<<manacher()<<endl;
    return 0;

省赛题:(改天调代码)

在这里插入代码片

以上是关于2019浙江省赛补题 +manacha算法的主要内容,如果未能解决你的问题,请参考以下文章

2019 hdu 第四场补题 (1 ,签到题

2018/11/30 周五集训队第七次测试赛补题题解

2019暑假集训 8/2

2019.8.24 TEST

2019/8/24 C语言回顾

[BUUOJ记录] [强网杯 2019]随便注(三种方法)