令$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. Linux中的文件使用FTP进行文件备份

    注意!!! 本文是在linux中进行ftp备份(备份到另一个linux服务器) 上传思路: 1.每次上传文件时, 后台接收文件, 使用transferTo上传到Linux服务器 2.把文件路径 + F ...

  2. SpringBoot入门08-整合Mabatis

    整合所需的依赖 注解方式和映射文件方式的mybatis都可以被整合进springboot 创建springboot的web项目后,在pom加入spring-mybatis和mysql-jdbc和thy ...

  3. ClickHouse 存算分离架构探索

    背景 ClickHouse 作为开源 OLAP 引擎,因其出色的性能表现在大数据生态中得到了广泛的应用.区别于 Hadoop 生态组件通常依赖 HDFS 作为底层的数据存储,ClickHouse 使用 ...

  4. Chrome 实时字幕

    Chrome 实时字幕

  5. WSL (Windows Subsystem for Linux)

    WSL (Windows Subsystem for Linux) :适用于 Linux 的 Windows 子系统. References Install WSL with a single com ...

  6. 图解Redis6中的9种数据结构,墙裂建议准备去面试的人先看(干货,建议收藏)

    如图所示,Redis中提供了9种不同的数据操作类型,他们分别代表了不同的数据存储结构. 图2-17 数据类型 String类型 String类型是Redis用的较多的一个基本类型,也是最简单的一种类型 ...

  7. JavaCPP快速入门(官方demo增强版)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. Scrum Meeting 0609

    零.说明 日期:2021-6-9 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 困难 qsy PM&前端 完成前端功能 ...

  9. Qt字符编码小知识

    1.VS2010默认编码是GBK,Qt5的内置编码是utf-8,想要在VS2010及其以上版本,优雅的使用utf-8的字符编码需要 // Coding: UTF-8(BOM) #if defined( ...

  10. Oracle 11g 常用sql记录

    --表备份 create table xxx_bak as select * from xxx; --表数据清除 truncate table xxx --锁表问题处理sql开始 select ses ...