令$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. NOIP模拟74

    前言 我就想说一句,T3 给了一个什么牛马大样例!!!!!!!!,气\(^{TM}\)死我!!!!!!! 我的 \(\mathcal{O}(n)\) 算法始终过不掉大样例我 TM ,要不然我就直接上矩 ...

  2. 题解 2020.10.24 考试 T2 选数

    题目传送门 题目大意 见题面. 思路 本来以为zcx.pxj变强了,后来发现是SPJ出问题了...考试的时候感觉有点人均啊...结果自己还是只想出来一半. 我们假设 \(f(x)=(\lfloor\f ...

  3. CVE-2017-11882 漏洞分析总结 新手漏洞分析详细教程

    CVE-2017-11882分析总结 注: 这篇随笔记录了CVE-2017-11882漏洞分析的整个过程,并介绍了相关调试软件的使用 漏洞信息 CVE-2017-11882属于缓冲区溢出类型漏洞,产生 ...

  4. 「软件测试实战教程系列(三)」弃繁就简,接口测试神器Postman|收藏版

    软件测试实战教程系列(三)弃繁就简,接口测试神器Postman|收藏版 Postman主要帮我们干了三件事: 1.把相关集合放到一个集合当中方便管理. 2.对指定接口发送请求. 3.断言 下面我们使用 ...

  5. (翻译)领域驱动设计实现-Implementing Domain Driven Design

    简介 Implementing Domain Driven Design 领域驱动设计实现 A practical guide for implementing the Domain Driven D ...

  6. 电脑日常使用bug记录

    1.由于电脑太卡了,于是决定关一点服务,一不小心,电脑无线无法使用了.启动无线服务时提示"windows无法启动wlan autoconfig服务错误1068依赖服务" 启动 Ex ...

  7. 深入理解Java虚拟机之类加载机制篇

    概述 ​ 虚拟机把描述类的数据从 Class 文件加载到内存中,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,就是虚拟机的类加载机制. ​ 在Java语言里面,类型的 ...

  8. LeetCode:回溯算法

    回溯算法 这部分主要是学习了 labuladong 公众号中对于回溯算法的讲解 刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 总结 概述 回溯是 DFS 中的一种技巧.回溯法采用 ...

  9. JVM:GC Roots

    JVM:GC Roots 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 JVM 垃圾回收的时候如何确定垃圾 什么是垃圾 简单来说就是内存中已经不再被使用的空间就 ...

  10. BUAAOO第四单元总结

    ---恢复内容开始--- 一.本单元两次作业的架构设计 第十三次作业:本次作业我创建了四个类,除去官方提供的Main和MyUmlInteraction类之外,还有Uclass和Ulinterface分 ...