2022NOIPA层联测6

问题 A: 【2022NOIP联测6 10月10日】构造字符串(str)

仔细的对着题解找不同,还是感觉就是一模一样……suddenlly求mex清空vis数组忘了0从1开始清,So WA 30,我又2了……

然后发现错误以为可以AC结果WA 60,忽然发现:不相同的字符之间要连边,但是不只有0!!任意长度的最长公共前缀的末尾都一定不相等!!!

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
const int maxn =  1003;
 
int m, n, fa[maxn], val[maxn], tot;
bool vis[maxn];
set<int> w[maxn];
 
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
 
struct node 
{
    int fr, to;
}b[maxn];
 
void add(int x, int y)
{
    b[++tot].fr = x; b[tot].to = y;
}
 
void add2(int x, int y)
{
    w[x].insert(y); w[y].insert(x);
}
 
int find(int x)
{
    if(x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}
 
int main()
{
    //freopen("str2.in", "r", stdin);
     
    n = read(); m = read();
    for(int i=1; i<=n; i++) fa[i] = i;
    for(int i=1; i<=m; i++)
    {
        int x = read(), y = read(), z = read();
        if(z)
        {
            for(int j=x,k=y; j<=x+z-1; j++,k++)
            {
                fa[find(j)] = fa[find(k)];
            }
            add(x+z, y+z);
        }
        else add(x, y);
    }
    for(int i=1; i<=tot; i++)
    {
        //printf("find : %d %d\n", find(b[i].fr), find(b[i].to));
        if(find(b[i].fr) == find(b[i].to)) 
        {
            printf("-1"); exit(0);
        }
        else add2(find(b[i].fr), find(b[i].to));
    }
    memset(val, -1, sizeof(val));
    for(int i=1; i<=n; i++)
    {
        if(val[find(i)] != -1) continue;
        int mex = 0;
        for(int j=0; j<=n; j++) vis[j] = 0;
        for(int x : w[find(i)])
        {
            //printf("val[%d] = %d\n", x, val[x]);
            //if(val[x] == mex) mex++;
            vis[val[x]] = 1;
        }
        while(vis[mex]) mex++;
        val[find(i)] = mex;
        //printf("val[%d] = %d\n", find(i), val[find(i)]);
    }
    for(int i=1; i<=n; i++)
    {
        printf("%d ", val[find(i)]);
    }
 
    return 0;
}
View Code

 

问题 B: 【2022NOIP联测6 10月10日】寻宝(treasure)

依然希望求救。。

问题已经解决!!

引子是一段对话:

我:可以问T2吗?

Chen_jr:……

我:对呀对呀!

Chen_jr:你过样例了吗,大样例?

我:过了呢,我有70 pts

Chen_jr:那是你dfs写错了吧

……

于是我到牛棚回声里鹤到了他的dfs。

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
const int maxn = 5e4 + 3;
 
int n, m, sta[maxn], top, k, q, fa[maxn];
char c[maxn], s[maxn];
bool vis[maxn];
 
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

inline int id(int x, int y)
{
    return (x-1)*m+y;
}

struct node 
{
    int next, to;
}a[maxn<<1];
int head[maxn], len;

void add(int x, int y)
{
    a[++len].to = y; a[len].next = head[x];
    head[x] = len;
}

int check(int x, int y)
{
    if(x == y) return true;
    vis[x] = 1; sta[++top] = x;
    for(int i=head[x]; i; i=a[i].next)
    {
        int v = a[i].to;
        if(vis[v]) continue;
        if(v == y) return true;
        if(check(v, y)) return true;
    }
    return false;
}

queue<pair<int, int> > qu;
void bfs(int x, int y)
{
    qu.push(make_pair(x, y));
    int tot = id(x, y);
    while(!qu.empty())
    {
        int i = qu.front().first, j = qu.front().second;
        qu.pop();
        if(i-1>=1 && s[id(i-1,j)] == '.' && fa[id(i-1,j)] == id(i-1,j)) 
        {
            qu.push(make_pair(i-1, j)); fa[id(i-1,j)] = tot;
        }
        if(j-1>=1 && s[id(i,j-1)]== '.' && fa[id(i,j-1)] == id(i,j-1))
        {
            qu.push(make_pair(i, j-1)); fa[id(i, j-1)] = tot;
        } 
        if(i+1<=n && s[id(i+1,j)] == '.' && fa[id(i+1,j)] == id(i+1,j))
        {
            qu.push(make_pair(i+1,j)); fa[id(i+1,j)] = tot;
        }
        if(j+1<=m && s[id(i,j+1)] == '.' && fa[id(i,j+1)] == id(i,j+1))
        {
            qu.push(make_pair(i,j+1)); fa[id(i,j+1)] = tot;
        }
    }
}

int main()
{
    n = read(); m = read(); k = read(); q = read();
    for(int i=1; i<=n*m; i++) fa[i] = i;
    for(int i=1; i<=n; i++)
    {
        scanf("%s", c+1);
        for(int j=1; j<=m; j++) s[id(i,j)] = c[j];
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(s[id(i,j)] == '.' && fa[id(i,j)] == id(i,j))
            {
                bfs(i, j);
            }
        }
    }
    for(int i=1; i<=k; i++)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        if(s[id(a1,b)] == '#' || s[id(c,d)] == '#' || fa[id(a1,b)] == fa[id(c,d)]) continue;
        add(fa[id(a1,b)], fa[id(c,d)]);
    }
    while(q--)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        printf("%d\n", check(fa[id(a1,b)], fa[id(c,d)]));
        while(top > 0) vis[sta[top--]] = false;
    }
 
    return 0;
}
这一版可以AC

然而依然不知道我的dfs为什么WA 70,区别只是预处理了一下啊,除了dfs的部分其他的什么都没变:

感谢char_phi:问题就是,由于加边的顺序问题,dfs时用这个点A指向的点B把这个点更新了,后来B又指向了一个点C,然后用C更新了B,但是它本来也可以更新A却没有更新,导致每一个错误的点都是应该输出1的输出了0。改进方法就是把边先加上最后再dfs,其实和下面那种Floyed差不太多了。

char_phi太巨啦!!while(1) {char_phi csps rp++; char_ph noip rp++;} char_phi yyds,此处省略%*2^(1e9+7),mod*2^(1234567891)……

作为一个OIer的快乐,不仅在于学习奇妙的方法来解决奇妙的问题,还在于同学之间真挚纯洁的友谊,hzoi早已成为了我的第二个家……hz的每一个平凡的角落,构成了世界上最美丽的风景;hz的每一幕平凡的场景,构成了人世间最绚烂的画卷,我爱这里的日出日落,爱这里的流云晚霞,爱这里的每一株草每一朵花,爱这里带有梦想气味的风……如果可以不长大,我多么希望永远在这里当一名高中生……

// 我感到很神奇,所以我看看这到底哪错了
#include &lt;bits/stdc++.h&gt;
 
using namespace std;
 
typedef long long ll;
const int maxn = 5e4 + 3;
 
int n, m, sta[maxn], top, k, q, fa[maxn];
char c[maxn], s[maxn];
bool vis[maxn];
 
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch &lt; &#39;0&#39; || ch &gt; &#39;9&#39;)
    {
        if(ch == &#39;-&#39;)
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch &gt;= &#39;0&#39; &amp;&amp; ch &lt;= &#39;9&#39;)
    {
        x = (x &lt;&lt; 1) + (x &lt;&lt; 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

inline int id(int x, int y){return (x-1)*m+y;}

struct node {int next, to;}a[maxn&lt;&lt;1];
int head[maxn], len;

void add(int x, int y){
    a[++len].to = y; a[len].next = head[x];
    head[x] = len;
}

queue&lt;pair&lt;int, int&gt; &gt; qu;
void bfs(int x, int y){
    qu.push(make_pair(x, y));
    int tot = id(x, y);
    while(!qu.empty()){
        int i = qu.front().first, j = qu.front().second;
        qu.pop();
        if(i-1&gt;=1 &amp;&amp; s[id(i-1,j)] == &#39;.&#39; &amp;&amp; fa[id(i-1,j)] == id(i-1,j)) 
            {qu.push(make_pair(i-1, j)); fa[id(i-1,j)] = tot;}
        if(j-1&gt;=1 &amp;&amp; s[id(i,j-1)] == &#39;.&#39; &amp;&amp; fa[id(i,j-1)] == id(i,j-1))
            {qu.push(make_pair(i, j-1)); fa[id(i, j-1)] = tot;}
        if(i+1&lt;=n &amp;&amp; s[id(i+1,j)] == &#39;.&#39; &amp;&amp; fa[id(i+1,j)] == id(i+1,j))
            {qu.push(make_pair(i+1,j)); fa[id(i+1,j)] = tot;}
        if(j+1&lt;=m &amp;&amp; s[id(i,j+1)] == &#39;.&#39; &amp;&amp; fa[id(i,j+1)] == id(i,j+1))
            {qu.push(make_pair(i,j+1)); fa[id(i,j+1)] = tot;}
    }
}
//
set&lt;int&gt; hv[maxn];
void dfs(int x, int l){
    vis[x] = 1; hv[l].insert(x);
    for(int i=head[x]; i; i=a[i].next){
        int y = a[i].to;
        if(vis[y]) continue;
        dfs(y, l);
    }
}
//
int check(int x, int y){
    if(x == y) return true;
    if(hv[x].find(y) != hv[x].end()) return true;
    return false;
}
int aa[50005], bb[50005], cc[50005], dd[50005];
int main()
{
    n = read(); m = read(); k = read(); q = read();
    for(int i=1; i&lt;=n*m; i++) fa[i] = i;
    for(int i=1; i&lt;=n; i++){
        scanf(&quot;%s&quot;, c+1);
        for(int j=1; j&lt;=m; j++) s[id(i,j)] = c[j];
    }
    for(int i=1; i&lt;=n; i++)
        for(int j=1; j&lt;=m; j++)
            if(s[id(i,j)] == &#39;.&#39; &amp;&amp; fa[id(i,j)] == id(i,j))
                bfs(i, j);
    for(int i=1; i&lt;=k; i++)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        aa[i] = a1, bb[i] = b, cc[i] = c, dd[i] = d;
        if(s[id(a1,b)] == &#39;#&#39; || s[id(c,d)] == &#39;#&#39; || fa[id(a1,b)] == fa[id(c,d)]) continue;
        //
        // memset(vis, 0, sizeof(vis));
        // dfs(fa[id(c,d)], fa[id(a1,b)]);
        add(fa[id(a1,b)], fa[id(c,d)]);
    }

    for (int i = 1 ; i &lt;= k ; ++ i){
        memset(vis, 0, sizeof(vis));
        dfs(fa[id(cc[i], dd[i])], fa[id(aa[i], bb[i])]);
    }

    while(q--)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        //
        printf(&quot;%d\n&quot;, check(fa[id(a1,b)], fa[id(c,d)]));
    }
 
    return 0;
}
AC
//对不同的地方有鲜明的 //标识
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
const int maxn = 5e4 + 3;
 
int n, m, sta[maxn], top, k, q, fa[maxn];
char c[maxn], s[maxn];
bool vis[maxn];
 
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

inline int id(int x, int y)
{
    return (x-1)*m+y;
}

struct node 
{
    int next, to;
}a[maxn<<1];
int head[maxn], len;

void add(int x, int y)
{
    a[++len].to = y; a[len].next = head[x];
    head[x] = len;
}

queue<pair<int, int> > qu;
void bfs(int x, int y)
{
    qu.push(make_pair(x, y));
    int tot = id(x, y);
    while(!qu.empty())
    {
        int i = qu.front().first, j = qu.front().second;
        qu.pop();
        if(i-1>=1 && s[id(i-1,j)] == '.' && fa[id(i-1,j)] == id(i-1,j)) 
        {
            qu.push(make_pair(i-1, j)); fa[id(i-1,j)] = tot;
        }
        if(j-1>=1 && s[id(i,j-1)]== '.' && fa[id(i,j-1)] == id(i,j-1))
        {
            qu.push(make_pair(i, j-1)); fa[id(i, j-1)] = tot;
        } 
        if(i+1<=n && s[id(i+1,j)] == '.' && fa[id(i+1,j)] == id(i+1,j))
        {
            qu.push(make_pair(i+1,j)); fa[id(i+1,j)] = tot;
        }
        if(j+1<=m && s[id(i,j+1)] == '.' && fa[id(i,j+1)] == id(i,j+1))
        {
            qu.push(make_pair(i,j+1)); fa[id(i,j+1)] = tot;
        }
    }
}
//
set<int> hv[maxn];
void dfs(int x, int l)
{
    vis[x] = 1; hv[l].insert(x);
    for(int i=head[x]; i; i=a[i].next)
    {
        int y = a[i].to;
        if(vis[y]) continue;
        dfs(y, l);
    }
}
//
int check(int x, int y)
{
    if(x == y) return true;
    if(hv[x].find(y) != hv[x].end()) return true;
    return false;
}

int main()
{
    n = read(); m = read(); k = read(); q = read();
    for(int i=1; i<=n*m; i++) fa[i] = i;
    for(int i=1; i<=n; i++)
    {
        scanf("%s", c+1);
        for(int j=1; j<=m; j++) s[id(i,j)] = c[j];
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(s[id(i,j)] == '.' && fa[id(i,j)] == id(i,j))
            {
                bfs(i, j);
            }
        }
    }
    for(int i=1; i<=k; i++)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        if(s[id(a1,b)] == '#' || s[id(c,d)] == '#' || fa[id(a1,b)] == fa[id(c,d)]) continue;
        //
        memset(vis, 0, sizeof(vis));
        dfs(fa[id(c,d)], fa[id(a1,b)]);
        add(fa[id(a1,b)], fa[id(c,d)]);
    }
    while(q--)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        //
        printf("%d\n", check(fa[id(a1,b)], fa[id(c,d)]));
    }
 
    return 0;
}
70

and 一题多解之并查集:(比我的bfs好看得多)

#include <bits/stdc++.h>
  
using namespace std;
  
typedef long long ll;
const int maxn = 5e4 + 3;
  
int n, m, sta[maxn], top, k, q, fa[maxn];
char c[maxn], s[maxn];
bool vis[maxn];
  
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
 
inline int id(int x, int y)
{
    return (x-1)*m+y;
}
 
int find(int x)
{
    if(x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}
 
inline void merge(int x, int y)
{
    x = find(x), y = find(y);
    if(x == y) return;
    fa[y] = x;
}
 
struct node 
{
    int next, to;
}a[maxn<<1];
int head[maxn], len;
 
void add(int x, int y)
{
    a[++len].to = y; a[len].next = head[x];
    head[x] = len;
}
 
int check(int x, int y)
{
    if(x == y) return true;
    vis[x] = 1; sta[++top] = x;
    for(int i=head[x]; i; i=a[i].next)
    {
        int v = a[i].to;
        if(vis[v]) continue;
        if(v == y) return true;
        if(check(v, y)) return true;
    }
    return false;
}
 
int main()
{
    n = read(); m = read(); k = read(); q = read();
    for(int i=1; i<=n*m; i++) fa[i] = i;
    for(int i=1; i<=n; i++)
    {
        scanf("%s", c+1);
        for(int j=1; j<=m; j++) s[id(i,j)] = c[j];
        if(i != 1)
        {
            for(int j=1; j<=m; j++)
            {
                if(c[j] == '.' && s[id(i-1,j)] == '.') merge(id(i,j), id(i-1,j));
            }
        }
        for(int j=2; j<=m; j++)
        {
            if(c[j] == '.' && c[j-1] == '.') merge(id(i,j-1), id(i,j)); 
        }
    }
    for(int i=1; i<=k; i++)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        if(s[id(a1,b)] == '#' || s[id(c,d)] == '#' || find(id(a1,b)) == find(id(c,d))) continue;
        add(find(id(a1,b)), find(id(c,d)));
    }
    while(q--)
    {
        int a1 = read(), b = read(), c = read(), d = read();
        printf("%d\n", check(find(id(a1,b)), find(id(c,d))));
        while(top > 0) vis[sta[top--]] = false;
    }
  
    return 0;
}
没错这一版是纯鹤

and一题多解之Floyed:(众所周知Floyed可以处理连通性,k最多只有100,老套路就是把它两边的点拿出来,然后就可以跑Floyed了)(能把一个套路用到每一个扯上关系的题里,所有变式应用自如,我不得不%%%)

#include<bits/stdc++.h>
using namespace std;
#define chu printf
#define _f(i,a,b)  for(register int i=(a);i<=(b);++i)
#define f_(i,a,b)  for(register int i=(a);i>=(b);--i)
#define inf 2147483647
#define ll long long 
#define rint register int
#define ull unsigned long long
inline ll re()
{
    ll x=0,h=1;char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')h=-1;
        ch=getchar();
    }
    while(ch<='9'&&ch>='0')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*h;
}
const int N=-1;
vector<bool>s[50000+10];//存矩阵(没告诉我具体) #=0;. =1
vector<int>id[50000+10];//方便维护节点编号
bool g[210][210],tag[50000+10];
int n,m,k,q,tot,code,belong[50000+10],belong2[50000+10],Code;
int fa[50000+100];//dx[5]={0,1,0,-1},dy[5]={1,0,-1,0};
char ss[50000+10];
struct Qy
{
    int x1,y1,x2,y2;
}que[100000+100];
inline bool Safe(int x,int y)
{
    if(x<=n&&x>=1&&y<=m&&y>=1)return 1;
    return 0;
}
inline int Father(int x)
{
    return (fa[x]==x)?x:(fa[x]=Father(fa[x]));
}
inline void Merge(int x,int y)
{
    //chu("merge:%d %d\n",x,y);
    int fx=Father(x),fy=Father(y);
    fa[fx]=fy;
}
int main()
{
   // freopen("treasure4.in","r",stdin);
   // freopen("1.out","w",stdout);
    n=re(),m=re(),k=re(),q=re();
    _f(i,1,n*m)fa[i]=i;
    _f(i,1,n)
    {
        scanf("%s",ss+1);
        id[i].push_back(0);
        s[i].push_back(0);
        _f(j,1,m)
        {
            if(ss[j]=='#')
            {
                //chu("%d %d is not can\n",i,j);
                s[i].push_back(0);
                id[i].push_back(0);
            }
            else 
            {
            //    chu("%d %d is can\n",i,j);
                s[i].push_back(1);
                ++tot;
                id[i].push_back(tot);
            }
        }
    }
    // chu("tot:%d\n",tot);
    // _f(i,1,n)
    // {
    //     _f(j,1,m)if(s[i][j])chu("1");else chu("0");
    //     chu("\n");
    // }
    _f(i,1,n)
    _f(j,1,m)
    {
        if(s[i][j]==0)continue;
        if(Safe(i,j+1)&&s[i][j+1]==1)Merge(id[i][j],id[i][j+1]);
        if(Safe(i+1,j)&&s[i+1][j]==1)Merge(id[i][j],id[i+1][j]);
    }
    //给每个联通块编号,belong[x]=code,
    _f(i,1,tot)
    if(fa[i]==i)belong[i]=++code;
    // chu("code:%d\n",code);
    _f(i,1,tot)belong[i]=belong[Father(i)];
    _f(i,1,k)//非常少,直接把涉及到的拿出来呗
    {
        int x1=re(),y1=re(),x2=re(),y2=re();
        que[i]={x1,y1,x2,y2};
        if(!tag[belong[id[x1][y1]]])
        {
           // deq[++deqcnt]=belong[id[x1][y1]];
            belong2[belong[id[x1][y1]]]=++Code;
            tag[belong[id[x1][y1]]]=1;
        }
        if(!tag[belong[id[x2][y2]]])
        {
           // deq[++deqcnt]=belong[id[x2][y2]];
            belong2[belong[id[x2][y2]]]=++Code;
            tag[belong[id[x2][y2]]]=1;
        }
    //    g[belong[id[x1][y1]]][belong[id[x2][y2]]]=1;
    }
    _f(i,1,k)
    {
        int x1=que[i].x1,y1=que[i].y1,x2=que[i].x2,y2=que[i].y2;
        int cd1=belong[id[x1][y1]],cd2=belong[id[x2][y2]];
        cd1=belong2[cd1],cd2=belong2[cd2];
        g[cd1][cd2]=1;
    }
    _f(k,1,Code)g[k][k]=1;
    _f(ker,1,Code)
    _f(i,1,Code)
    _f(j,1,Code)
    g[i][j]=g[i][j]|(g[i][ker]&&g[ker][j]);

    _f(i,1,q)
    {
        int x1=re(),y1=re(),x2=re(),y2=re();
        int fx=Father(id[x1][y1]),fy=Father(id[x2][y2]);
        if(fx==fy)
        {
            chu("1\n");
        }
        else 
        {
            int cd1=belong[id[x1][y1]],cd2=belong[id[x2][y2]];
            if(!belong2[cd1]||!belong2[cd2])//有的没归纳
            {
                chu("0\n");
            }
            else
            {
                cd1=belong2[cd1],cd2=belong2[cd2];
                if(g[cd1][cd2])chu("1\n");
                else chu("0\n");
            }
        }
    }
    return 0;
}
显然这是caorong大佬的码风,我懒得抄了

 

问题 C: 【2022NOIP联测6 10月10日】序列(seq)

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 1e6 + 3;
const ll inf = 1e17;

int n, m;
ll a[maxn], b[maxn], ans, fa[maxn], fb[maxn];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

int main()
{
    n = read(); m = read();
    for(int i=1; i<=n; i++)
    {
        a[i] = read(); b[i] = read();
        fa[i] = fa[i-1] + a[i]; fb[i] = fb[i-1] + b[i];
    }
    while(m--)
    {
        int pos = read(); ll k = read();
        int p = 0, p1 = pos;
        for(int i=1; i<pos; i++)
        {
            if(fb[p]*k-fa[p] < fb[i]*k-fa[i]) p = i;
        }
        for(int i=pos; i<=n; i++)
        {
            if(fa[p1]-fb[p1]*k < fa[i]-fb[i]*k) p1 = i;
        }
        ans = fa[p1]-fa[p]+fb[p]*k-fb[p1]*k;
        printf("%lld\n", ans);
    }

    return 0;
}
TLE 50

 

问题 D: 【2022NOIP联测6 10月10日】构树(tree)

并不了解prufer序列的我以最暴力的方式生成了一棵树:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 12;
const ll inf = 1e17;

int n, m, ext[maxn], cnt, num, ans[maxn], las[maxn], fa[maxn];
ll tot;
bool vis[maxn];
map<pair<int, int>, int> mp;
map<ll, ll> mp2;

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

void dfs(int a, int m)
{
    if(a > m)
    {
        ll pat = 0;
        for(int i=2; i<=n; i++)
        {
            pat = (pat<<1)+(pat<<3)+fa[i];
        }
        if(mp2.count(pat)) return;
        ans[num]++; mp2[pat] = ++tot;
        return;
    }
    int sz = cnt;
    for(int i=1; i<=sz; i++)
    {
        for(int j=las[i]+1; j<=n; j++)
        {
            if(vis[j]) continue;
            vis[j] = 1; ext[++cnt] = j; las[cnt] = 1;
            fa[j] = ext[i];
            if(mp.count(minmax(ext[i], j))) num++;
            int fl = las[i]; las[i] = j;
            dfs(a+1, m);
            vis[j] = 0; cnt--;
            if(mp.count(minmax(ext[i], j))) num--;
            las[i] = fl;
        }
    }
}

int main()
{
    n = read();
    for(int i=1; i<n; i++)
    {
        int x = read(), y = read();
        mp[minmax(x, y)] = i;
    }
    vis[1] = 1;
    ext[++cnt] = 1; las[cnt] = 1;
    dfs(1, n-1);
    for(int i=0; i<n; i++)
    {
        printf("%d ", ans[i]);
    }

    return 0;
}
RE 20

 

posted @ 2022-10-10 17:16  Catherine_leah  阅读(47)  评论(10编辑  收藏  举报
/* */