3.25省选测试

$15+100+25$,还是太菜了,结论题和数据结构还是有点问题

以后文章大概不会在洛谷更新了,洛谷机房的人会看到一些我的吐槽.,然后我被吐槽...这个博客园机房并没有人知道(毕竟全机房就我写博客)

其实我并不是很喜欢现在机房的氛围,我希望看到的是一起卷题,一起做一件喜欢的事,互相帮助,每天很积极很乐观,思想很正派,每个人都不虚伪,成绩很真实,也不怕挫折,不因为虚荣去欺骗,这样的一个团队才是我喜欢的,或许我永远不能在这个团队看到了......(好希望被一个团队收留,有没有人要我啊$QAQ$)

$T1$

考场上想到了暴力建树,贪心求期望,只能过$m=2^k$

$m=2^k$结论比较显然,我们把概率二进制分解之后,显然每个有$1$的位置占一个子树就好了

$Ans=\sum_{i}i\times 2^{-i}$

考试时候倒是知道这个式子,我没想到这个竟然在任何时候都能用...

两个结论式$:$

$f(2\times p)=2(f(p)+p)\ \ \ \ \ [p<=\frac{1}{2}]$

$f(2\times p-1)=2(f(p)+p)\ \ \ \ \ [p>\frac{1}{2}]$

首先对于奇数的情况(偶数就是在基环树上多了几个分支)

奇数可以通过这个式子回到自己,那么就可以列出方程解出来了

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define MAXM 10000005
#define MAXN 1000005
using namespace std;
int Inv2,Invm,sum,top,res,n;
int my_2[MAXM],Ans[MAXM],sta[MAXM],a[MAXN];
bool bl[MAXM],vis[MAXM];
int my_pow(int a,int b)
{
    int res=1;
    while(b)
    {
          if(b&1)
          {
               res=(res*a)%mod;
          }
          a=(a*a)%mod;
          b>>=1;
    }
    return res;
}
void Init(int Maxn)
{
     my_2[0]=1;
     Inv2=my_pow(2,mod-2);
     for(int i=1;i<=Maxn;i++)
     {
          my_2[i]=(my_2[i-1]*Inv2)%mod;
     }
}
int Nxt(int x)
{
    x<<=1;
    if(x>=sum) x-=sum;
    return x;
}
void Get(int x)
{
     int to=Nxt(x);
     int v=x*Invm%mod,k=1;
     while(to!=x)
     {
            v+=my_2[k++]*to%mod*Invm%mod;
            v%=mod;
            to=Nxt(to);
     }
     Ans[x]=v*my_pow((1-my_2[k]+mod)%mod,mod-2)%mod;
     bl[x]=true;
}
signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum+=a[i];
    }
    Init(sum);
    Invm=my_pow(sum,mod-2);
    for(int i=0;i<=sum-1;i++)
    {
        if(!vis[i])
        {
            int now=i;
            while(!vis[now])
            {
                  sta[++top]=now;
                  vis[now]=true;
                  now=Nxt(now);
            }
            if(!bl[Nxt(sta[top])])
            {
                Get(sta[top--]);
            }
            while(top)
            {
                  now=sta[top--];
                  Ans[now]=Inv2*Ans[Nxt(now)]+now*Invm;
                  Ans[now]%=mod;
                  bl[now]=true;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        res+=Ans[a[i]];
        res%=mod;
    }
    cout<<res<<"\n";
}

 


T2

二分图染色+补图+背包

#include<bits/stdc++.h>
#define INF 2147483647
#define MAXM 1100000
#define MAXN 5005
using namespace std;
int Num[3],Ans=INF,Min,n,m;
int head[MAXM],nxt[MAXM],col[MAXM],to[MAXM],A[MAXM],tot,cnt;
bitset<1005>Sit[1005];
struct node
{
       int num0,num1;
}val[MAXN];
void add(int u,int v)
{
     tot++;
     to[tot]=v;
     nxt[tot]=head[u];
     head[u]=tot;
}
void dfs(int now,int fa,int num)
{
     col[now]=num;
     Num[col[now]]++;
     for(int i=head[now];i;i=nxt[i])
     {
          int y=to[i];
          if(y==fa) continue;
          if(col[now]==col[y]) 
          {
              puts("-1");
              exit(0);
          }
          if(col[y]==-1)dfs(y,now,(num+1)%2);
     }
}
bitset<2005>dp[2];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        Sit[u][v]=1;
        Sit[v][u]=1;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            if(Sit[i][j]==0) add(i,j),add(j,i);
        }
    }
    memset(col,-1,sizeof(col));
    for(int i=1;i<=n;i++)
    {
        if(col[i]==-1) 
        {
            Num[0]=Num[1]=0,dfs(i,i,0),val[++cnt].num0=Num[0],val[cnt].num1=Num[1];
//            cout<<Num[0]<<" "<<Num[1]<<endl;
        }
    
    }
    dp[0][0+1000]=1;
    //A-B的差的情况 
    for(int i=1;i<=cnt;i++)
    {
        int now=i%2;
        int pre=now^1;
        dp[now]=(dp[pre]>>val[i].num0<<val[i].num1)|(dp[pre]<<val[i].num0>>val[i].num1);
    }
    for(int i=0;i<=1000;i++)
    {
        if(dp[cnt%2][1000+i]||dp[cnt%2][1000-i])
        {
            cout<<min((n+i)/2,(n-(n+i)/2));
            break;
        }    
    }
//    system("pause");
}

 

$T3$

暴力斜挂,只过了一个$sub$

确实不太知道最小的点怎么挂了,$/dk$

首先维护一个区间$mex$最大值,就很不太能维护的样子,主要是修改不是很好修

想到了离线处理,考虑枚举答案

假设这段区间$0-(y-1)$出现了,那么我们只需要判定$y$有没有存在即可

我们将出现$y$的位置标为$black$,没出现标为$white$,对序列建立线段树,没有被完全覆盖的区间标记为灰色,对于一组区间询问,直接查询是否全为白色即可

先考虑一下,树套树,内层维护树维护修改,外层树维护询问,大概每次修改只需要对应区间的权值线段树都加入一个数字,查询一下没出现的最小值就好了

大概上是理解了

其实就是我们对于每一个修改,把修改放在线段树上,通过维护关键点来更新答案

我们的关键点是上到下是灰变白,灰变黑节点的儿子,我们考虑这个点的答案是什么 ,就是这些黑点的没出现的最小值,其实很像曾经的一个在节点维护$pq$的思路

又透彻了一遍,大概明白了,对于每次修改直接放关键点就好了,然后答案就是这些数字所有的没出现的最小的,由于每个事没出现的,那么我们找一下最小的没出现的,然后在所有区间找个最大的就好了

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define rs ((x<<1)|1)
#define MAXN 200500
#define ls (x<<1)
using namespace std;
inline int rd(){
    int r = 0 , w = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0') {if(ch == '-') w = -1; ch = getchar();} 
    while(ch >='0' && ch <='9') {r = r * 10 + ch -'0'; ch = getchar();}
    return r * w;
}
int q,n=200010;
struct range
{
    int l,r;
    range(){}
    range(int _l,int _r=0){l=_l;r=_r;}
    friend bool operator < (range a,range b)
    {
        return a.l==b.l?a.r<b.r:a.l<b.l;
    }
};
struct node
{
    int l,r,ans;
    set<int>s;
}tr[MAXN<<2];
map<pair<int,int>,bool>Black,Gray;
set<range>rg[MAXN];
void Gaib(int x,int k,bool opt)
{
    if(Black.count(make_pair(x,k))||Gray.count(make_pair(x,k)))return;
    if(tr[x].s.find(k)==tr[x].s.end()&&opt) tr[x].s.insert(k);
    else if(opt==0) tr[x].s.erase(k);
    if(!tr[x].s.empty())
    {
        if(tr[x].l==tr[x].r) tr[x].ans=INF;
        else tr[x].ans=max(tr[ls].ans,tr[rs].ans);
        tr[x].ans=min(tr[x].ans,*(tr[x].s.begin()));
    }
    else if(tr[x].l==tr[x].r) tr[x].ans=INF;
    else tr[x].ans=max(tr[ls].ans,tr[rs].ans);
}
void push_up(int x,int k)
{
    bool opt=Gray.count(make_pair(x,k));
    if(tr[x].l==tr[x].r) tr[x].ans=INF;
    else
    {
        Gaib(ls,k,opt);
        Gaib(rs,k,opt);
        tr[x].ans=max(tr[ls].ans,tr[rs].ans);
    }
    if(!tr[x].s.empty()) tr[x].ans=min(tr[x].ans,*(tr[x].s.begin()));
}
void color_black(int x , int k)
{
    tr[x].s.erase(k);
    if(!Black.count(make_pair(x,k))) Black.insert(make_pair(make_pair(x,k),1));
}
void update(int x,int l,int r,int k)
{
    if(l<=tr[x].l&&tr[x].r<=r)
    {
        color_black(x,k);
        push_up(x,k);
        return;
    }
    if(!Gray.count(make_pair(x,k))) Gray.insert(make_pair(make_pair(x,k),1));
    tr[x].s.erase(k);
    int mid=tr[x].l+tr[x].r>>1;
    if(l<=mid) update(ls,l,r,k);
    if(r>mid)  update(rs,l,r,k);
    push_up(x,k);
}
int query(int x,int l,int r)
{
    if(l<=tr[x].l&&tr[x].r<=r) return tr[x].ans;
    int mid = tr[x].l+tr[x].r>>1;
    int res=0;
    if(l<=mid) res=max(res,query(x<<1,l,r));
    if(r>mid)  res=max(res,query(rs,l,r));
    if(res==0) res=INF;
    if(!tr[x].s.empty()) res=min(res,*(tr[x].s.begin()));
    return res;
}
void Insert(set<range>&s,int l,int r,int k)
{
    auto pre=s.lower_bound(range(l));
    if(pre!=s.begin())
    {
        pre--;
        if(pre->r>r) return;
        l=max(l,pre->r+1);
    }
    if(l>r) return;
    int last=l;
    for(auto its=s.lower_bound(range(l));its!=s.end();)
    {
        if(its->l>r) break;
        if(last<=its->l-1) update(1,last,its->l-1,k);
        if(its->r>=r)
        {
            if(l<=its->l-1) s.insert(range(l,its->l-1));
            return;
        }
        last=its->r+1;
        s.erase(its++);
    }
    if(last<=r) update(1,last,r,k);
    s.insert(range(l,r));
}
void build(int x ,int l,int r){
    tr[x].ans=INF;
    tr[x].l=l;
    tr[x].r=r;
    if(l==r) return;
    int mid=l+r>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
}
int S;
signed main()
{
    freopen("starlight.in","r",stdin);
    freopen("starlight.out","w",stdout);
    build(1,1,n);
    for(int i=1;i<=n;i++) tr[1].s.insert(i);
    tr[1].ans=1;
    q=rd();
    while(q--)
    {
        int opt=rd();
        if(opt==1)
        {
            int k=rd(),l=rd(),r=rd();
            k=k^S,l=l^S,r=r^S;
            Insert(rg[k+1],l+1,r+1,k+1);
        }
        else
        {
            int l=rd(),r=rd();
            l=l^S,r=r^S;
            int ans=query(1,l+1,r+1)-1;
            S+=ans;
            cout<<ans<<"\n";
        }
    }
    return 0;
}

 


毕竟我是我,我看不惯的人,无法改变就不必在意,终成路人而已,无须为此耗时,一笑而过即可

 

posted @ 2022-03-25 18:09  Authentic_k  阅读(49)  评论(0编辑  收藏  举报