noi2019模拟测试赛(四十七)

T1与运算(and)

题意:

​ 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所有排列的\(\Sigma_i f_i\)的最大值。

题解:

​ dp,记\(dp_i\)表示前面的数与和为\(i\)的最大值,转移要一个超集的东西,fwt搞一搞就行了。

#include<bits/stdc++.h>
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define of(i,l,r) for(int i=l;i>=r;i--)
#define fe(i,u) for(int i=head[u];i;i=e[i].next)
#define el putchar('\n')
#define ta putchar('    ')
using namespace std;
typedef long long ll;
inline void open(const char *s)
{
    #ifndef ONLINE_JUDGE
    char str[20];
    sprintf(str,"%s.in",s);
    freopen(str,"r",stdin);
//  sprintf(str,"%s.out",s);
//  freopen(str,"w",stdout);
    #endif
}
inline int rd()
{
    static int x,f;
    x=0;f=1;
    char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return f>0?x:-x;
}
const int N=1<<20;
ll n,cnt[N],f[N];

inline void fwt(ll *a,int len)
{
    for(int i=2;i<=len;i<<=1)
        for(int j=0;j<len;j+=i)
            for(int k=0;k<(i>>1);++k)a[j+k]+=a[j+k+(i>>1)];
}

int main()
{
    n=rd();fo(i,1,n)++cnt[rd()];
    fwt(cnt,N);
    fo(i,1,N-1)for(int j=1;j<N;j<<=1)if(i&j)f[i]=max(f[i],f[i^j]+cnt[i]*j);
    cout<<f[N-1]<<endl;
    return 0;
}

T2 序列(sequence)

题意:

​ 随机生成一个数列:

  • \(a_0=0\)

  • \(\forall i>0,a_i\)有\(p_i\)的概率等于\(a_{i-1}+1\),有\(1-p_i\)的概率等于\(0\)。

    求\(\Sigma_{i=1}^na^2\)的期望。

题解:

​ 签到推式子题。dp转移就是枚举最后一段连续+1的长度。式子大力差分后可以线性做。代码就不放了。

T3 平均值(average)

题意:

​ 给你一个序列\(a_i\),求:
\[
\Sigma_{l=1}^n\Sigma_{r=l}^n\frac{ mex(a_l,a_l+1,\cdots,a_r)}{r-l+1}
\]

题解:

​ 式子转成:
\[
\Sigma_{i=1}^{max}\Sigma_{l=1}^n\Sigma_{r=l}^n\frac{ [mex(a_l,a_l+1,\cdots,a_r)\ge i]}{r-l+1}
\]
​ 然后就是对于每一个\(l\),求\(r\),贡献是倒数的前缀和。线段树2分+区间覆盖。然后这个区间覆盖要加一个函数,用技巧可以实现。

#include<bits/stdc++.h>
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define of(i,l,r) for(int i=l;i>=r;i--)
#define fe(i,u) for(int i=head[u];i;i=e[i].next)
#define el putchar('\n')
#define ta putchar('    ')
using namespace std;
typedef long long ll;
typedef vector<int> vi;
inline void open(const char *s)
{
    #ifndef ONLINE_JUDGE
    char str[20];
    sprintf(str,"%s.in",s);
    freopen(str,"r",stdin);
//  sprintf(str,"%s.out",s);
//  freopen(str,"w",stdout);
    #endif
}
namespace IO{
const int N=(1<<26)+10;
char buf[N],*H,*T;
inline char Get()
{
    if(H==T)T=(H=buf)+fread(buf,1,N,stdin);
    return H==T?-1:*H++;
}
inline int rd()
{
    static int x,f;
    x=0;f=1;
    char ch=Get();
    for(;ch<'0'||ch>'9';ch=Get())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=Get())x=x*10+ch-'0';
    return f>0?x:-x;
}
}using IO::rd;
const int N=500010,Inf=1000000000,mod=998244353;
int n,m,inv[N],s[N],ss[N],rt;
vi vec[N];

inline int pls(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int mns(int a,int b){return a<b?a-b+mod:a-b;}
inline int mul(int a,int b){return (ll)a*b%mod;}

namespace Seg{
#define lson tr[o].ls,l,mid
#define rson tr[o].rs,mid+1,r
#define qlson lson,L,min(mid,R)
#define qrson rson,max(mid+1,L),R
struct tree{
    int ls,rs,mn,sum,ps,tag;
    tree(){ls=rs=mn=sum=tag=0;}
}tr[N<<1];int cnt=0;

inline void calc(int o,int d,int l,int r){tr[o].sum=mns(ss[d-l],ss[d-r-1]);tr[o].mn=tr[o].tag=d;}
inline void pushup(int o)
{
    tr[o].sum=pls(tr[tr[o].ls].sum,tr[tr[o].rs].sum);
    tr[o].mn=min(tr[tr[o].ls].mn,tr[tr[o].rs].mn);
}
inline void pushdown(int o,int l,int mid,int r)
{static int ls,rs;
    if(!tr[o].tag)return;
    ls=tr[o].ls,rs=tr[o].rs;
    calc(ls,tr[o].tag,l,mid);
    calc(rs,tr[o].tag,mid+1,r);
    tr[o].tag=0;
}

void build(int &o,int l,int r)
{
    o=++cnt;if(l==r)return tr[o].ps=s[n-l+1],void();
    int mid=(l+r)>>1;build(lson);build(rson);
    tr[o].ps=pls(tr[tr[o].ls].ps,tr[tr[o].rs].ps);
}
void modify(int o,int l,int r,int L,int R,int d)
{if(L>R)return;
    if(l==L&&r==R)return calc(o,d,l,r);
    int mid=(l+r)>>1;pushdown(o,l,mid,r);
    if(L<=mid)modify(qlson,d);
    if(R>mid)modify(qrson,d);
    pushup(o);
}
int qsum(int o,int l,int r,int L,int R)
{if(L>R)return 0;
    if(l==L&&r==R)return mns(tr[o].ps,tr[o].sum);
    int mid=(l+r)>>1,res=0;pushdown(o,l,mid,r);
    if(L<=mid)res=pls(res,qsum(qlson));
    if(R>mid)res=pls(res,qsum(qrson));
    return res;
}
int query(int o,int l,int r,int L,int R,int d)
{
    if(l==r)return tr[o].mn<d?l:l-1;
    int mid=(l+r)>>1;pushdown(o,l,mid,r);
    if(l==L&&r==R){
        if(tr[tr[o].rs].mn<d)return query(qrson,d);
        return query(qlson,d);
    }
    int res=mid;
    if(R>mid)res=query(qrson,d);
    if(res>mid)return res;
    if(L<=mid)res=query(qlson,d);
    return res;
}

}

int main()
{open("c");
    n=rd();inv[0]=inv[1]=1;
    fo(i,1,n){
        vec[rd()].push_back(i);
        if(i-1)inv[i]=mns(0,mul(mod/i,inv[mod%i]));
    }
    int ans=0;m=n;
    fo(i,1,n)s[i]=pls(s[i-1],inv[i]);
    fo(i,1,n)ss[i]=pls(ss[i-1],s[i]);
    Seg::build(rt,1,n);
    fo(t,0,500000){
        if(!vec[t].size())break;
        int hh=0;
        of(i,vec[t].size()-1,0){
            if(++hh==1)m=min(m,vec[t][i]);
            int x=Seg::query(rt,1,n,1,m,vec[t][i]);
            int ql=i?vec[t][i-1]+1:1;
            Seg::modify(rt,1,n,ql,min(m,x),vec[t][i]);
        }
        if(!hh)break;
        ans=pls(ans,Seg::qsum(rt,1,n,1,m));
    }
    printf("%d\n",ans);
    return 0;
}

noi2019模拟测试赛(四十七)的更多相关文章

  1. 2017.8.1 Noip2018模拟测试赛(十七)

    日期: 八月第一天  总分: 300分  难度: 提高 ~ 省选    得分: 100分(不应该啊!) 题目目录: T1:战争调度 T2:选数 T3:由乃的OJ 赛后心得: MMP,首先第一题花了大概 ...

  2. [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania

    [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见&quo ...

  3. 2016北京集训测试赛(十七)Problem C: 数组

    Solution 线段树好题. 我们考虑用last[i]表示\(i\)这个位置的颜色的上一个出现位置. 考虑以一个位置\(R\)为右端点的区间最远能向左延伸到什么位置: \(L = \max_{i \ ...

  4. 2016北京集训测试赛(十七)Problem B: 银河战舰

    Solution 好题, 又是长链剖分2333 考虑怎么统计答案, 我场上的思路是统计以一个点作为结尾的最长上升链, 但这显然是很难处理的. 正解的方法是统计以每个点作为折弯点的最长上升链. 具体的内 ...

  5. 2016北京集训测试赛(十七)Problem A: crash的游戏

    Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \ ...

  6. 2018.8.8 Noip2018模拟测试赛(二十一)

    日期: 八月七号  总分: 300分  难度: 提高 ~ 省选    得分: 112分(OvO) 题目目录: T1:幸福的道路 T2:Solitaire T3:Flags 赛后心得: 第一题裸树d啊! ...

  7. 2018.8.7 Noip2018模拟测试赛(二十)

    日期: 八月七号  总分: 300分  难度: 提高 ~ 省选    得分: 100分(呵呵一笑) 题目列表: T1:SS T2:Tree Game T3:二元运算 赛后反思: Emmmmmm…… 开 ...

  8. 2018.8.6 Noip2018模拟测试赛(十九)

    日期: 八月六号  总分: 300分  难度: 提高 ~ 省选    得分: 10分(MMP) 题目目录: T1:Tree T2:异或运算 T3:Tree Restoring 赛后反思: Emmmmm ...

  9. 2017.8.2 Noip2018模拟测试赛(十八)

     日期: 八月二日  总分: 300分  难度: 提高 ~ 省选  得分: 40分(又炸蛋了!!) 题目列表: T1:分手是祝愿 T2:残缺的字符串 T3:树点涂色 赛后心得: 哎,T1求期望,放弃. ...

随机推荐

  1. 紫书 例题 10-21 UVa 11971(连续概率)

    感觉这道题的转换真的是神来之笔 把木条转换成圆,只是切得次数变多一次 然后只要有一根木条长度为直径就租不成 其他点的概率为1/2^k 当前这个点的有k+1种可能 所以答案为1 - (k+1)/2^k ...

  2. gcc/g++命令参数笔记

    1. gcc -E source_file.c -E,只执行到预编译.直接输出预编译结果. 2. gcc -S source_file.c -S,只执行到源代码到汇编代码的转换,输出汇编代码. 3. ...

  3. 【Codeforces Round #423 (Div. 2) C】String Reconstruction

    [Link]:http://codeforces.com/contest/828/problem/C [Description] 让你猜一个字符串原来是什么; 你知道这个字符串的n个子串; 且知道第i ...

  4. Android输入法扩展之远程输入法

    近年来,互联网电视開始火热,乐视TV,小米TV,近期爱奇艺也在大肆的招人做爱奇艺电视.当然还有更被关注的苹果电视.事实上,这个趋势非常正常,也非常合理,传统单纯的接收电视节目的电视已经太传统了.是该被 ...

  5. Android ImageView设置图片原理(下)

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 写完上一篇后,总认为介绍的知识点不多,仅仅是一种在UI线程解析载入图片.两种在子线程解析,在UI线程 ...

  6. js 阻断网页选中和右键

    $(document).bind("contextmenu", function () { return false; }); $(document).bind("sel ...

  7. double long float类型读入读出 double取模 fmod

    The library of fmod is #include <cmath> #include<cstdio> #include<cstdlib> #includ ...

  8. BZOJ3511: 土地划分

    [传送门:BZOJ3511] 简要题意: 给出n个点,m条边,每个点有A和B两种形态,一开始1为A,n为B 给出VA[i]和VB[i],表示第i个点选择A和B形态的价值 每条边给出x,y,EA,EB, ...

  9. 洛谷P2598 [ZJOI2009]狼和羊的故事

    题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈 ...

  10. ES6学习笔记(八)第七种类型Symbol

    1.概述 ES5 的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突.如果有一种 ...