Day1 T2:最大前缀和

枚举答案集合(不直接枚举答案数,相当于状态的离散化),这个集合成为答案当且仅当存在方案使得答案集合的排列后缀和>=0(如果<0就可以去掉显然更优),答案补集的前缀和<0(不能再延伸)。预处理方案数。最后统计的时候注意要枚举答案子集的第一个元素,它不需要满足后缀和>=0。O(2^n*n)。

 #include<bits/stdc++.h>
using namespace std;
const int mod=;
typedef long long ll;
const int N=;
int n,Max,a[N],sum[N],f[N],g[N],ans;
void up(int &x,int y){x=((ll)x+y)%mod;}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
Max=<<n;
for (int i=;i<Max;i++)
for (int j=;j<=n;j++)
if (i&(<<(j-))) up(sum[i],a[j]);
f[]=;
for (int i=;i<Max;i++)//后缀和>=0
if (sum[i]>=)
{
for (int j=;j<=n;j++)
if (i&(<<(j-))) up(f[i],f[i^(<<(j-))]);
}
g[]=;
for (int i=;i<Max;i++)//前缀和<0
if (sum[i]<)
{
for (int j=;j<=n;j++)
if (i&(<<(j-))) up(g[i],g[i^(<<(j-))]);
}
for (int i=;i<Max;i++)
for (int j=;j<=n;j++)
if (i&(<<(j-)))
up(ans,(ll)f[i^(<<(j-))]*g[i^(Max-)]%mod*sum[i]%mod);
printf("%d\n",((ll)ans+mod)%mod);//注意ans有可能是负数!
return ;
}

Day2

T1:星际穿越  贪心+树上倍增

要想到肯定贪心走能走的较远点。单调肯定不会让你好好求最短路,建树是一个思路。

性质:当起点在终点右边时,起点要走到终点,必然只会往右走一步,接下来一直往左走。

每个点朝能够到达的点中覆盖区间左端点最左的点连边,如果它想要走最远,选择这一点一定最优。

往右走一步也是类似的道理,一定是往右走能够走到的点中覆盖区间左端点最左的点最优。(具体实现可以按照覆盖区间左端点排序)如果往右再往左两步没有直接往左两步优的话,一定不会往右走。

如果一步可以走到也一定不会往右。(询问的时候特判一下即可)

询问的时候对于[1..r]求走到x的距离和。倍增使得x在[1..r]外且l[x]在[1..r]内,分成[1..l[x])和[l[x]..r]两段通过走到当前x再走到终点。预处理一下[1..l[i])到i的距离的和。O((n+q)logn)。

 #include<bits/stdc++.h>
using namespace std;
const int N=;
int l[N],a[N][],par[N][],n,pre[N],q,fa[N],mx,b[N],rt[N];
int getmin(int x,int y)
{
return l[x]<l[y]?x:y;
}
void init()
{
for (int i=;i<=n;i++) a[i][]=i;
for (int j=;j<=;j++)
for (int i=;i+(<<j)-<=n;i++)
a[i][j]=getmin(a[i][j-],a[i+(<<(j-))][j-]);
}
int qry(int l,int r)
{
int len=;
while ((<<(len+))<=r-l+) len++;
return getmin(a[l][len],a[r-(<<len)+][len]);
}
bool cmp(int A,int B) {return l[A]<l[B];}
int calc(int x,int y)//[1..x] to y
{
int ans=;
if (rt[y])
{
if (l[y]<=x) ans+=x-l[y]+,x=l[y]-;
y=rt[y];ans+=x;
}
if (!x) return ans;
int sum=;
for (int i=;i>=;i--)//倍增使得l[终点]跳进[1..x]
if (l[par[y][i]]>x) y=par[y][i],sum+=(<<i);
if (l[y]>x) y=par[y][],sum++;
return ans+pre[y]+sum*(l[y]-)+(sum+)*(x-l[y]+);
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&l[i]);
init();
for (int i=;i<=n;i++) fa[i]=par[i][]=qry(l[i],i-);//找到可以跳到最左边的点作为父亲
for (int j=;j<=;j++)//树上倍增
for (int i=;i<=n;i++)
par[i][j]=par[par[i][j-]][j-]; for (int i=;i<=n;i++) b[i]=i;//处理会向右走一步的情况
sort(b+,b+n+,cmp);
for (int i=;i<=n;i++)
{
for (int j=mx+;j<b[i];j++) rt[j]=b[i];
mx=max(mx,b[i]);
}
for (int i=;i<=n;i++)
if (l[rt[i]]>=l[fa[i]]) rt[i]=;
for (int i=;i<=n;i++)//处理前缀和[1..l[i]) to i
if (fa[i]==) pre[i]=;else pre[i]=pre[fa[i]]+l[fa[i]]-+*(l[i]-l[fa[i]]); scanf("%d",&q);
while (q--)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
int a=calc(r,x)-calc(l-,x),b=r-l+;
int Gcd=__gcd(a,b);
a/=Gcd;b/=Gcd;printf("%d/%d\n",a,b);
}
return ;
}

T2:神仙的游戏

border相交有循环节的性质。问题是快速检查循环节的合法性。(我都想到bitset了T_T)

如果循环节长度为len时,对应位置的i,j一个为0一个为1,那么循环节长度为len的因数的都不可行。(有一个部分分给的就是暴力枚举01的位置)

fft处理对应位置的01是否有冲突,需要多项式平移。枚举当前循环节长度的倍数判断可行。时间复杂度O(nlogn)。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=;
const int root=;
const int N=;
char s[N];
int _n,l,w[N],pos[N],A[N],B[N],sl;
int ksm(int x,int y)
{
int res=;
while (y) {if (y&) res=(ll)res*x%mod; x=(ll)x*x%mod; y>>=;}
return res;
}
void init(int n)
{
l=;
while ((<<l)<=n) l++;
_n=(<<l);int ww=ksm(root,<<-l);
w[]=;
for (int i=;i<_n;i++)
w[i]=(ll)w[i-]*ww%mod,
pos[i]=(i&)?pos[i-]|(<<(l-)):pos[i>>]>>;
}
void fft(int *a)
{
for (int i=;i<_n;i++) if (i<pos[i]) swap(a[i],a[pos[i]]);
int len=,id=_n;
for (int i=;i<l;i++)
{
int wn=w[id>>=];
for (int j=;j<_n;j+=len*)
for (int k=j,ww=;k<j+len;k++)
{
int l=a[k],r=(ll)a[k+len]*ww%mod;
a[k]=((ll)l+r)%mod;a[k+len]=((ll)l-r+mod)%mod;
ww=(ll)ww*wn%mod;
}
len<<=;
}
}
int main()
{
scanf("%s",s+);sl=strlen(s+);
for (int i=;i<=sl;i++)
if (s[i]=='') A[i]=;
else if (s[i]=='') B[sl-i+]=;
init(sl*+);fft(A);fft(B);
for (int i=;i<_n;i++) A[i]=(ll)A[i]*B[i]%mod;
fft(A);reverse(A+,A+_n);
int inv_n=ksm(_n,mod-);
for (int i=;i<_n;i++) A[i]=(ll)A[i]*inv_n%mod;
ll ans=(ll)sl*sl;
for (int i=;i<sl;i++)
{
int fl=;
for (int j=i;j<=sl&&fl;j+=i)
fl&=(!A[sl-j+]&&!A[sl+j+]);
if (fl) ans^=(ll)(sl-i)*(sl-i);
}
printf("%lld\n",ans);
return ;
}

PKUSC订正的更多相关文章

  1. 数据库订正脚本性能优化两则:去除不必要的查询和批量插入SQL

    最近在做多数据库合并的脚本, 要将多个分数据库的表数据合并到一个主数据库中. 以下是我在编写数据订正脚本时犯过的错误, 记录以为鉴. 不必要的查询 请看以下语句: regiondb = db.Houy ...

  2. mysql 数据库数据订正

    mysql 数据库数据订正 http://blog.itpub.net/22664653/viewspace-717175/ 工作过程中时常遇到数据订正的需求,该操作本身不难.操作时要求能够保持回滚~ ...

  3. [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC

    [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...

  4. PKUSC 2018 题解

    PKUSC 2018 题解 Day 1 T1 真实排名 Link Solution 考虑对于每一个人单独算 每一个人有两种情况,翻倍和不翻倍,他的名次不变等价于大于等于他的人数不变 设当前考虑的人的成 ...

  5. [LOJ 6435][PKUSC 2018]星际穿越

    [LOJ 6435][PKUSC 2018]星际穿越 题意 给定 \(n\) 个点, 每个点与 \([l_i,i-1]\) 之间的点建立有单位距离的双向边. \(q\) 组询问从 \(x\) 走到 \ ...

  6. [LOJ 6433][PKUSC 2018]最大前缀和

    [LOJ 6433][PKUSC 2018]最大前缀和 题意 给定一个长度为 \(n\) 的序列, 求把这个序列随机打乱后的最大前缀和的期望乘以 \(n!\) 后对 \(998244353\) 取膜后 ...

  7. [LOJ 6432][PKUSC 2018]真实排名

    [LOJ 6432][PKUSC 2018]真实排名 题意 给定 \(n\) 个选手的成绩, 选中其中 \(k\) 个使他们的成绩翻倍. 对于每个选手回答有多少种方案使得他的排名不发生变化. \(n\ ...

  8. Diary -「PKUSC 2021」游记

      出游回来自然而然(?)地进入生产低谷的兔子只能写写游记了 qwq. Day -1 实时反馈赛制不是为防止你被数据调戏,而是给你调戏数据的机会. --鲁迅   PKU 一贯的 \(32\) 发提交实 ...

  9. [游记] pkusc 2021 游记

    流水账 Day-4 写了ICPC的一道DP,有点细节,虽然写得有点难受,但挺好玩 Day-3 写了PKUSC2018最水的一题 是随机开的题 Day-2 可以去pkusc了,从今天中午开始停课 刚吃完 ...

随机推荐

  1. VirtualBox安装CentOS系统

    1. 准备材料 虚拟机软件: VirtualBox 系统iso版本:CentOS-7-x86_64-DVD-1611.iso 虚拟机软件下载地址: https://www.virtualbox.org ...

  2. nginx信号及平滑升级

    1.nginx信号 nginx进程处理命令: kill -signals PID PID即nginx进程ID signals的参数解释如下所示: TERM,INT快速关闭进程 QUIT优雅的关闭,如果 ...

  3. 【学术篇】The Xuanku Inversion Magic学习笔记

    退役之前写的 然后因为退役就咕咕咕了... 后来发现数学考试能用的到个鬼就发布出来了QwQ 主要是方便自己没登录的时候查阅... 显然子集什么的是没有学会的QwQ 所以学OI的话不要看本文!!!!!& ...

  4. day06 python is == 编码 解码

    day06 python   一. is 和 == 的区别     == :比较, 判断, 比较的是值: 可以比较数字, 字符串, 列表, 元组, 字典,等     is :是 比较, 比较的是内存地 ...

  5. 72.Properties(配置文件)

    Properties(配置文件):主要用于存储配置文件到硬盘上面和读取配置文件 public class Properties extends Hashtable<Object,Object&g ...

  6. leetcode-12双周赛-1243-数组变换

    题目描述: 自己的提交: class Solution: def transformArray(self, arr: List[int]) -> List[int]: if len(arr) & ...

  7. “二维数组”?

    首先说明C中是不存在所谓的"多维数组"的. int array[a][b]:声明的是一个有a个元素的数组,每个数组元素是一个含b个元素的数组. 上述声明正确的说法是,数组的数组. ...

  8. javascript的简洁的写法

    每种语言都有它特别的地方,对于JavaScript来说,使用var就可以声明任意类型的变量,这门脚本语言看起来很简单,然而想要写出优雅的代码却是需要不断积累经验的.本文利列举了JavaScript初学 ...

  9. 贪心——cf708b

    先求0,1的个数,然后贪心输出01即可 #include<bits/stdc++.h> using namespace std; #define ll long long ll a,b,c ...

  10. 上传漏洞科普[1]-文件上传表单是Web安全主要威胁

    为了让最终用户将文件上传到您的网站,就像是给危及您的服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种 常见的要求,因为它有助于提高您的业务效率.在Facebook ...