P13086 题解
1-index 比较没法做,使用 0-index。
直接求排列复合看上去就不太能压进
现在考虑
计算
发现
现在需要做两件事:首先,根据输入求出
首先需要一个编码系统把
这里一个数的两个二进制位被拆开了。代码中,
现在对排列
显然这四个东西在那个
实际上,通过精细实现可以只用一个按位与操作。这需要用右移操作消掉没有用的二进制位。
下面计算
由于排列的性质,求交之后的结果至多只有一个位为
发现四个集合的并可以写成
其中
现在需要求出
发现
最复杂的情况是
将三个
最后发现答案为
如果实现足够精细,可以做到
当然,因为使用右移操作对齐,所以算出来的
接着卡常可以做到
这里只给出
#include<bits/stdc++.h>
using namespace std;
#define uint unsigned int
enum{NOT,AND,OR,XOR,LSH,RSH,POPC};
const uint N=1<<16,K=15;
struct node{
int type;//NOT AND OR XOR LSH RSH POPCNT
bool fl,fr;
uint to,L,R;
void get(bool& fl,uint& x){
if (fl) cout<<"N ";cout<<x;
}
void output(){
cout<<to<<' ';
if (type==NOT) cout<<"NOT";
if (type==AND) cout<<"AND";
if (type==OR) cout<<"OR";
if (type==XOR) cout<<"XOR";
if (type==LSH) cout<<"LSH";
if (type==RSH) cout<<"RSH";
if (type==POPC) cout<<"POPCNT";
cout<<' ';get(fl,L);
if (type&&type<6){
cout<<' ';
get(fr,R);
}
cout<<'\n';
}
};
vector<node> ans;
void push(uint to,int type,bool fl,uint L,bool fr,uint R){ans.emplace_back((node){type,fl,fr,to,L,R});}
void build(){
int p[4]={0,1,2,3},iv[4];
for (int i=0;i<24;++i){
uint s=0,t=0;
for (int j=0;j<4;++j){s|=p[j]<<(j*4);iv[p[j]]=j;}
for (int j=0;j<4;++j) s|=iv[j]<<(j*4+2);
t=s;s=0;
for (int o=0;o<4;++o) for (int p=0;p<4;++p) if ((t>>o*4+p)&1) s|=1<<o+p*4;
t=s;s=0;
for (int i=0;i<16;++i) if ((t>>i)&1){
if (i&4) s|=1<<(i^8);
else s|=1<<i;
}
cout<<s<<'\n';
next_permutation(p,p+4);
}
}
uint x[4]={4,5,6,7},y[4]={8,9,10,11},a[4]={12,13,14,15},b[6]={16,17,18,19,20,21},c[4]={22,23,24,25},A4=a[0],A2=a[1],A1=a[3],A0=a[2],A=1,B=27,C=26,D=2,A21=b[0],A20=8,A11=b[1],A10=9,P=28,Q=29;
void solve(){
push(B,RSH,0,D,1,8);
push(D,RSH,0,D,1,4);
push(C,RSH,0,A,1,12);
push(A,AND,0,A,1,K);
push(99,XOR,0,A,0,C);
push(100,XOR,0,B,0,D);
push(b[2],AND,0,99,0,100);
push(a[0],XOR,0,C,0,D);
push(a[1],XOR,0,A,0,B);
push(A21,AND,0,C,0,D);
push(A11,AND,0,A,0,B);
for (int i=0;i<3;++i) push(b[i],POPC,0,b[i],0,0);
}
void calc(){
push(3,OR,0,a[0],0,a[1]);
push(3,XOR,0,3,1,K);
push(3,AND,0,3,1,K);
push(3,LSH,0,3,1,4);
for (int i=0;i<3;++i) push(3,OR,0,3,0,b[i]);
push(3,OR,0,3,1,13);
push(3,POPC,0,3,0,0);
push(3,RSH,0,3,1,1);
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
build();
solve();
calc();
cout<<ans.size()<<endl;
for (auto x:ans) x.output();
return 0;
}