2018多校第二场

版权声明:欢迎大佬指正! https://blog.csdn.net/sinat_36215255/article/details/81226850

j题想复杂了,其实只要换就会减少逆序数,所以答案是,n*min(x,y);

G题,注意b为1~n的排列,所以,我们用一个数来记录当前的a值,当ai 等于 bi 时,我们更新该点,因为是1~N的排列,并且每次都是加一更新,所以复杂度没有想象中那么高,我们注意维护一下区间值,当发现ai==bi时更新单点就好了

补题的时候,把数组开小了,字符数组,还有mi数组忘了乘4

#include <iostream>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <queue>
#include <cmath>
#define lson root<<1,l,mid
#define rson  root<<1|1,mid+1,r
using namespace std;
const int inf =0x3f3f3f3f;
const int maxn = 1e5+5;
int tree[maxn*4];
int lazy[maxn*4];
int b[maxn];
int mi[maxn*4];
void pushup(int root)
{
    mi[root] = min(mi[root<<1],mi[root<<1|1]);
    tree[root] = tree[root<<1] + tree[root<<1|1];
}
void pushdown(int root)
{
    if(lazy[root])
    {
         mi[root<<1] += lazy[root];
         mi[root<<1|1] += lazy[root];
         lazy[root<<1|1] += lazy[root];
         lazy[root<<1] += lazy[root];
         lazy[root] = 0;
    }
}
void build(int root, int l,int r)
{
    lazy[root] = 0;
    tree[root] = 0;
    if(l==r)
    {
        mi[root] = b[l];
        tree[root] = 0;
        return ;
    }
    int mid = (l+r)>>1;
    build(lson);
    build(rson);
    pushup(root);
}
void update1(int root,int l,int r)
{
    if(mi[root]<=0&&l==r)
    {
         mi[root] +=b[l];
         tree[root]++;
         return ;
    }
    int mid = (l+r)>>1;
    pushdown(root);
    if(mi[root*2]<=0) update1(lson);
    if(mi[root*2+1]<=0) update1(rson);
    pushup(root);
}
void update(int root,int l,int r,int ul,int ur)
{
    if(ul<=l && ur>=r)
    {
        lazy[root]--;
        mi[root]--;
        if(mi[root]<=0)
        {
            update1(root,l,r);
        }
        return ;
    }
    pushdown(root);
    int mid = (l+r)>>1;
    if(ul<=mid) update(lson,ul,ur);
    if(ur>mid) update(rson,ul,ur);
    pushup(root);

}
int query(int root,int l,int r,int ql,int qr)
{
    if(ql<=l&&qr>=r)
    {
        return tree[root];
    }

        pushdown(root);
        int mid = (l+r)>>1;
        int ans = 0;
        if(ql<=mid) ans+=query(lson,ql,qr);
        if(qr>mid)  ans+=query(rson,ql,qr);
        pushup(root);
        return ans;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1; i<=n; i++)
            scanf("%d",&b[i]);
        build(1,1,n);
        char qu[50];
        while(m--)
        {
           int l,r;
           scanf("%s%d%d",qu,&l,&r);
           if(qu[0]=='a')
           {
               update(1,1,n,l,r);
           }
           else
           {
               int ans = query(1,1,n,l,r);
               printf("%d\n",ans);
           }
        }
    }

    return 0;
}

E题跟上一场的某个题目一样,都很有意思,但是就是推不出来,

这里放上一位大佬的博客,说实话,这个证明很秀,我第一遍没看懂

https://blog.csdn.net/AC_hunter/article/details/81214033

代码如下:

#include <iostream>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include<map>
#include <vector>
#include <queue>
#define lson root*2,l,mid
#define rson  root*2+1,mid+1,r
using namespace std;
const int inf =0x3f3f3f3f;
const int maxn = 3e3+5;

int mp[maxn][maxn];

int main()
{

    int n = 2000;
    int p = 47;
    for(int x=0; x<p*p; x++)
    {
        int k = x/p;
        int b = x%p;
        for(int i=0 ; i<p ; i++)
        {
            int y = i*p + (k*i + b)%p;
            mp[x][y] = 1;
        }
    }
    cout<<n<<endl;
    for(int i=0; i<n; i++)
    {
        for(int  j=0; j<n; j++)
            cout<<mp[i][j];
        cout<<endl;
    }
    return 0;
}

再就是补C题,dls的做法很机智,真不愧是全场唯一ak的队伍。

在奇数点上面自己加边来跑欧拉回路

代码如下:

猜你喜欢

转载自blog.csdn.net/sinat_36215255/article/details/81226850