令$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. 利用Conda尝鲜Python 3.10

    1 简介 就在几天前,Python3.10的第一个正式版本3.10.0发布,之前我们只是从其各个测试版本中捕风捉影地知晓了一些可能加入的新特性,而在正式版本中,我们得以一睹其正式加入的诸多新特性. 本 ...

  2. docker-compose 搭建mongo集群

    创建目录 在每台机器上操作此步骤 一.在编写容器文件之前的注意事项: 1.yaml文件的指令前端不能使用tab键只能使用空格 2.storage: 指令的对接只能使用 : 不能使用 = 冒号的后面要跟 ...

  3. NOIP模拟74

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

  4. SpringBoot打包到docker(idea+传统方式)

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 目录 1. 方式1.通过idea 远程发布 1.1 修改docker.service文件 1. 进入服务器 2. 修改ExecStart行为下面内容 ...

  5. JavaScript04

    分离绑定事件 使用分离方式绑定元素事件可以使用页面元素与JavaScript代码完全分离,有利于代码分工和维护,是目前开发主流,分为两步: 1.获取需要绑定事件的元素 语法:根据id属性值取元素节点 ...

  6. jdbc简单学生管理系统

    这个是java连接mysql数据库的一个简单学生系统,通过jdbc连接数据库. 工具类 JDBCuntils. package Student; import java.io.IOException; ...

  7. Coursera Deep Learning笔记 深度卷积网络

    参考 1. Why look at case studies 介绍几个典型的CNN案例: LeNet-5 AlexNet VGG Residual Network(ResNet): 特点是可以构建很深 ...

  8. Codeforces Round #573 (Div. 2) D题题解

    一.题目 ​ Tokitsukaze, CSL and Stone Game ​ Tokitsukaze和CSL正在玩一些石头游戏. ​ 一开始,有n堆的石头,第i堆石头数记为 \(a_i\),两人轮 ...

  9. allegro查看线宽的方法

  10. switch中case...用法-c语言

    ... 表示范围 case 0...4;   // error case 5 ... 9; // ok eg 1: char ch = 4; switch(ch) { case 1: printf(& ...