令$A=\{a_{1},a_{2},...,a_{s}\}$,若$k\not\in A$,那么恰存在一个$A'\subseteq A$使得$c_{k}=\bigoplus_{x\in A'}c_{x}$

存在性:若不存在,将$k$加入$A$中仍然为合法的集合,与$|A|$最大矛盾

唯一性:若存在多个,将其中两个集合异或(即保留在这两个集合中出现奇数次的元素),显然这个异或的结果非空且所有元素异或和为0,与$A$为合法的集合矛盾

(为了方便,称$A'$为$k$的表示集合)

此时,限制即$\forall k\not\in A$且$x\in A',v_{x}\le v_{k}$(其中$A'$为$k$的表示集合)

必要性:若不满足此性质,显然用$k$替换$x$价格和更小

充分性:考虑合法方案$B$,满足$|B|=|A|$,来证明$\sum_{x\in A}v_{x}\le \sum_{x\in B}v_{x}$

考虑$k\in A$且$k\not\in B$,同理恰存在一个$B'\subseteq B$使得$c_{k}=\bigoplus_{x\in B'}c_{x}$

若$\forall x\in B'$且$x\not\in A$,其的表示集合若包含$k$,那么即有$v_{k}\le v_{x}$,用$k$替换$x$不劣

若所有$x$的表示集合都不包含$k$,那么将这些表示集合和$(A\cap B')\cup\{k\}$异或,显然这个异或的结果非空($k$必然只出现一次)且所有元素异或和为0,矛盾

因此,重复此过程,每一次$|A\cap B|$恰好增加1,那么必然会有$|A\cap B|=|A|=|B|$,也即$A=B$

关于如何求$A'$可以使用线性基,复杂度为$o(nm)$(实现中比较懒用了$o(\frac{n^{2}m}{\omega})$)

(关于价格和最大的方案类似,也可以得到若干个不等式)

得到不等式后,即是一个保序回归的问题,做法参考[tc14634]ExtremeSpanningTrees

(另外,其中的引理中$S$应改为$[0,10^{6}]$,因为是平方,所以加1的答案增加$\Delta$但减1不一定使答案增加$-\Delta$)

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1005
4 #define M 105
5 #define ll unsigned long long
6 #define oo 0x3f3f3f3f
7 #define vi vector<int>
8 struct ji{
9 int nex,to;
10 ll len;
11 }edge[N*M*4];
12 queue<int>q;
13 bitset<N>BT,bt[M];
14 int E,n,m,x,w[N],vis[N],head[N],work[N],a[N],d[N],bl[N],ans[N],lim[N][N];
15 ll sum,c[N],val[M];
16 void add(ll k,int x){
17 ll o=1;
18 BT.reset();
19 BT[x]=1;
20 for(int i=63;i>=0;i--)
21 if (k&(o<<i)){
22 if (!val[i]){
23 val[i]=k;
24 bt[i]=BT;
25 }
26 k^=val[i];
27 BT^=bt[i];
28 }
29 }
30 void query(ll k,int x,int p){
31 ll o=1;
32 BT.reset();
33 for(int i=63;i>=0;i--)
34 if (k&(o<<i)){
35 BT^=bt[i];
36 k^=val[i];
37 }
38 for(int i=1;i<=n;i++)
39 if (BT[i]){
40 if (!p)lim[i][x]=1;
41 else lim[x][i]=1;
42 }
43 }
44 ll sqr(ll k){
45 return k*k;
46 }
47 bool cmp(int x,int y){
48 return bl[x]<bl[y];
49 }
50 void init(){
51 E=0;
52 memset(head,-1,sizeof(head));
53 }
54 void add(int x,int y,ll z){
55 edge[E].nex=head[x];
56 edge[E].to=y;
57 edge[E].len=z;
58 head[x]=E++;
59 if (E&1)add(y,x,0);
60 }
61 bool bfs(){
62 memset(d,oo,sizeof(d));
63 d[0]=0;
64 q.push(0);
65 while (!q.empty()){
66 int k=q.front();
67 q.pop();
68 for(int i=head[k];i!=-1;i=edge[i].nex)
69 if ((edge[i].len)&&(d[edge[i].to]==oo)){
70 d[edge[i].to]=d[k]+1;
71 q.push(edge[i].to);
72 }
73 }
74 return d[n+1]<oo;
75 }
76 ll dfs(int k,ll s){
77 if (k>n)return s;
78 for(int &i=work[k];i!=-1;i=edge[i].nex)
79 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
80 ll p=dfs(edge[i].to,min(s,edge[i].len));
81 if (p){
82 edge[i].len-=p;
83 edge[i^1].len+=p;
84 return p;
85 }
86 }
87 return 0;
88 }
89 void dinic(){
90 while (bfs()){
91 memcpy(work,head,sizeof(work));
92 while (dfs(0,1e12));
93 }
94 }
95 void dfs(int k){
96 if (vis[k])return;
97 vis[k]=1;
98 for(int i=head[k];i!=-1;i=edge[i].nex)
99 if (edge[i].len)dfs(edge[i].to);
100 }
101 void dfs(int l,int r,int x,int y){
102 if (x==y){
103 for(int i=l;i<=r;i++)ans[a[i]]=x;
104 return;
105 }
106 int mid=(x+y>>1);
107 init();
108 for(int i=l;i<=r;i++){
109 ll wx=sqr(w[a[i]]-mid),wy=sqr(w[a[i]]-mid-1);
110 if (wx>wy){
111 bl[a[i]]=1;
112 add(0,i,wx-wy);
113 }
114 else{
115 bl[a[i]]=0;
116 add(i,n+1,wy-wx);
117 }
118 }
119 for(int i=l;i<=r;i++)
120 for(int j=l;j<=r;j++)
121 if (lim[a[i]][a[j]])add(i,j,oo);
122 dinic();
123 memset(vis,0,sizeof(vis));
124 dfs(0);
125 for(int i=head[0];i!=-1;i=edge[i].nex)
126 if (!vis[edge[i].to])bl[a[edge[i].to]]=0;
127 for(int i=head[n+1];i!=-1;i=edge[i].nex)
128 if (vis[edge[i].to])bl[a[edge[i].to]]=1;
129 sort(a+l,a+r+1,cmp);
130 for(int i=l;i<=r+1;i++){
131 if ((bl[a[i]])||(i>r)){
132 if (l<i)dfs(l,i-1,x,mid);
133 if (i<=r)dfs(i,r,mid+1,y);
134 return;
135 }
136 }
137 }
138 int main(){
139 scanf("%d%d",&n,&m);
140 for(int i=1;i<=n;i++)scanf("%llu",&c[i]);
141 for(int i=1;i<=n;i++)scanf("%d",&w[i]);
142 for(int i=1;i<=m;i++){
143 scanf("%d",&x);
144 add(c[x],x);
145 vis[x]=1;
146 }
147 for(int i=1;i<=n;i++)
148 if (!vis[i])query(c[i],i,0);
149 memset(vis,0,sizeof(vis));
150 memset(val,0,sizeof(val));
151 for(int i=1;i<=m;i++){
152 scanf("%d",&x);
153 add(c[x],x);
154 vis[x]=1;
155 }
156 for(int i=1;i<=n;i++)
157 if (!vis[i])query(c[i],i,1);
158 for(int i=1;i<=n;i++)a[i]=i;
159 dfs(1,n,0,1e6);
160 for(int i=1;i<=n;i++)sum+=sqr(ans[i]-w[i]);
161 printf("%lld",sum);
162 }

[loj3301]魔法商店的更多相关文章

  1. 7-05. 魔法优惠券(25) (数学 ZJU_PAT)

    题目链接:http://www.patest.cn/contests/ds/7-05 在火星上有个魔法商店,提供魔法优惠券.每一个优惠劵上印有一个整数面值K,表示若你在购买某商品时使用这张优惠劵.能够 ...

  2. PTA数据结构与算法题目集(中文) 7-39魔法优惠券 (25 分)

    PTA数据结构与算法题目集(中文)  7-39魔法优惠券 (25 分) 7-39 魔法优惠券 (25 分)   在火星上有个魔法商店,提供魔法优惠券.每个优惠劵上印有一个整数面值K,表示若你在购买某商 ...

  3. P1875 佳佳的魔法药水

    P1875 佳佳的魔法药水 题目描述 发完了 k 张照片,佳佳却得到了一个坏消息:他的 MM 得病了!佳佳和大家一样焦急 万分!治好 MM 的病只有一种办法,那就是传说中的 0 号药水 ……怎么样才能 ...

  4. vijos:P1285佳佳的魔法药水

    背景 发完了k张照片,佳佳却得到了一个坏消息:他的MM得病了!佳佳和大家一样焦急万分!治好MM的病只有一种办法,那就是传说中的0号药水……怎么样才能得到0号药水呢?你要知道佳佳的家境也不是很好,成本得 ...

  5. 洛谷 P1875 佳佳的魔法药水

    P1875 佳佳的魔法药水 题目描述 发完了 k 张照片,佳佳却得到了一个坏消息:他的 MM 得病了!佳佳和大家一样焦急 万分!治好 MM 的病只有一种办法,那就是传说中的 0 号药水 --怎么样才能 ...

  6. 洛谷—— P1875 佳佳的魔法药水

    https://www.luogu.org/problemnew/show/1875 题目背景 发完了 k 张照片,佳佳却得到了一个坏消息:他的 MM 得病了!佳佳和大家一样焦急 万分!治好 MM 的 ...

  7. test20190803 夏令营NOIP训练19

    60+100+0=160 贪婪大陆 面对蚂蚁们的疯狂进攻,小FF的Tower defence宣告失败--人类被蚂蚁们逼到了Greed Island上的一个海湾.现在,小FF的后方是一望无际的大海, 前 ...

  8. 「Vijos 1285」「OIBH杯NOIP2006第二次模拟赛」佳佳的魔法药水

    佳佳的魔法药水 背景 发完了k张照片,佳佳却得到了一个坏消息:他的MM得病了!佳佳和大家一样焦急万分!治好MM的病只有一种办法,那就是传说中的0号药水--怎么样才能得到0号药水呢?你要知道佳佳的家境也 ...

  9. 【完全开源】知乎日报UWP版(下篇):商店APP、github源码、功能说明。Windows APP 良心出品。

    目录 说明 功能 截图+视频 关于源码和声明 说明 陆陆续续大概花了一个月的时间,APP算是基本完成了.12月份一直在外出差,在出差期间进行了两次功能完善,然后断断续续修补了一些bug,到目前为止,我 ...

随机推荐

  1. 双指针之滑动窗口(长度最小的子数组 和 和为s的连续正数序列)

    双指针之滑动窗口 (长度最小的子数组:和为s的连续正数序列) 1, 什么时候使用? (与子数组/字符串 有关的题目)~如果给了某个具体值的target,即用滑动窗口 不然就双指针(一般做法,左边< ...

  2. 架构师必备:MySQL主从延迟解决办法

    上一篇文章介绍了MySQL主从同步的原理和应用,本文总结了MySQL主从延迟的原因和解决办法.如果主从延迟过大,会影响到业务,应当采用合适的解决方案. MySQL主从延迟的表现 先insert或upd ...

  3. pycharm设置文件中显示模板内容

    pycharm中设置自己的文件模板  File>>Settings>>Editor>>File and Code Templates 选择文件类型或者输入文件类型 ...

  4. Flink sql 之 TopN 与 StreamPhysicalRankRule (源码解析)

    基于flink1.14的源码做解析 公司内有很多业务方都在使用我们Flink sql平台做TopN的计算,今天同事突然问到我,Flink sql 是怎么实现topN的 ? 蒙圈了,这块源码没看过啊 , ...

  5. .net 5.0 ref文件夹的作用

    ref目录里的dll是一个名为参考组件的东西,微软MSDN给的解释是 参考组件是一种特殊类型的程序集,仅包含表示库的公共API面所需的最小元数据数量.它们包括用于在构建工具中引用程序集时重要的所有成员 ...

  6. 【二食堂】Beta - 事后分析

    事后分析 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Beta阶段我们首先要对文本标注方式进行优化,其次时添加好友系统,实现邀请好友共同标注的功能. ...

  7. UltraSoft - Beta - Scrum Meeting 7

    Date: May 23rd, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 暂无 Liuzh 前端 编写忘记密码界面 Kkkk 前端 暂无 王fuji 前端 ...

  8. the Agiles Scrum Meeting 4

    会议时间:2020.4.12 20:00 1.每个人的工作 今天已完成的工作 yjy:基本完成广播功能,修复bug issues:小组任务1-增量开发组 Bug:冲刺 wjx:继续实现注销功能的后端 ...

  9. proto3语法记录

    protobuf 是谷歌的语言无关,平台无关,可扩展的,高效的结构化数据序列化机制,比xml和json的序列化的速度更快,此处记录一下 proto3 的语法,防止以后忘记. 注意:proto3 语法需 ...

  10. Noip模拟80 2021.10.18

    预计得分:5 实际得分:140?????????????? T1 邻面合并 我考场上没切掉的大水题....(证明我旁边的cty切掉了,并觉得很水) 然而贪心拿了六十,离谱,成功做到上一篇博客说的有勇气 ...