【fake题解】[NOI2013]向量内积
【fake题解】[NOI2013]向量内积
做法1
大暴力。哪里不会T哪里。
做法2
- 所有数都%=k不影响结果。(废话
- k的取值只有2和3,所以肯定是要分类讨论的。k=2肯定简单些啦。
k=2
出现的数只会有0和1
两个0或1相乘,乘积就是与之后的值
所以可以把向量用bitset存起来,这样计算就是\(O(\frac{d}{32})\),结果是3.125
然后上暴力,\(O(\frac{n^2}{2}\times 3.125)\),能卡过(事实并非如此,飞起了)
k=3
先讨论前14个点的k=3
出现的数只会有012
bitset似乎无法完成这项任务
然而实际上可以的
想一想0和其它的乘,贡献都是0
1和2单独考虑
1*1=1
2*2=1
1*2=2
把1看成0,2看成1,这就是个xor
所以用两个bitset,一个存0的,一个存2的,搞定
复杂度和上面一样
再讨论后面的
可以用int代替bitset,计算的复杂度降到\(O(1)\)
然后。。。
gzy和我用一样的方法A掉了。。。
// 我死活过不去的代码
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<bitset>
#include<ctime>
#include<cstdlib>
#include<set>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
using namespace std;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,d,k,x,p[100001];
namespace k2{
il vd main(){
for(rg int i=1;i<=n;++i)p[i]=i;
bitset<100>s[20001];
for(rg int i=1;i<=n;++i)
for(rg int j=0;j<d;++j)
s[i][j]=gi()&1;
for(rg int i=1;i<=n;++i){
x=rand()%n+1;
swap(s[i],s[x]);
swap(p[i],p[x]);
}
for(rg int i=n;i;--i)
for(rg int j=i+1;j<=n;++j)
if(((s[i]&s[j]).count()&1)==0){
if(p[i]>p[j])swap(p[i],p[j]);
printf("%d %d\n",p[i],p[j]);
return;
}
printf("-1 -1");
}
}
namespace k32{
il vd main(){
for(rg int i=1;i<=n;++i)p[i]=i;
bitset<100>s[100001],S[100001],a;
for(rg int i=1;i<=n;++i)
for(rg int j=0;j<d;++j){
x=gi()%3;
s[i][j]=x==2;
S[i][j]=x==0;
}
for(rg int i=1;i<=n;++i){
x=rand()%n+1;
swap(s[i],s[x]);
swap(S[i],S[x]);
swap(p[i],p[x]);
}
for(rg int i=n;i;--i)
for(rg int j=i+1;j<=n;++j){
a=s[i]^s[j];
x=(a&(~(S[i]|S[j]))).count()*2;
x+=d-(a|(S[i]|S[j])).count();
if(x%3==0){
if(p[i]>p[j])swap(p[i],p[j]);
printf("%d %d\n",p[i],p[j]);
return;
}
}
puts("-1 -1");
}
}
namespace k31{
il int count(int x){
int ret=0;
while(x)++ret,x-=x&-x;
return ret;
}
struct yyb{int a,b,c;};
bool operator <(const yyb&a,const yyb&b){
return a.a==a.b?a.b<b.b:a.b<b.b;
}
il vd main(){
int a;
yyb s[100001];
set<pair<int,int> >l,ll;
int N=n,n=0,A,B;
for(rg int i=1;i<=N;++i){
A=B=0;
for(rg int j=0;j<d;++j){
x=gi()%3;
if(x==2)A|=1<<j;
if(x==0)B|=1<<j;
}
if(l.find(make_pair(A,B))==l.end())++n,s[n]=(yyb){A,B,i},l.insert(make_pair(A,B));
//else if(ll.find(make_pair(A,B))==ll.end())++n,s[n]=(yyb){A,B,i},ll.insert(make_pair(A,B));
}
sort(s+1,s+n+1);
for(rg int i=1;i<n;++i)
for(rg int j=i+1;j<=n;++j){
a=s[i].a^s[j].a;
x=count((a&(~(s[i].b|s[j].b))))*2;
x+=d-count((a|(s[i].b|s[j].b)));
if(x%3==0){
if(s[i].c>s[j].c)swap(s[i].c,s[j].c);
printf("%d %d\n",s[i].c,s[j].c);
return;
}
}
printf("-1 -1");
}
}
int main(){
srand(time(NULL));
n=gi(),d=gi(),k=gi();
if(k==2)k2::main();
else if(d<=30)k31::main();
else k32::main();
return 0;
}
// gzy无敌AC代码
#include<bitset>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define RG register
#define REP(i,a,b) for(RG int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(RG int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
inline int read()
{
int sum=0,p=1;char ch=getchar();
while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
if(ch=='-')p=-1,ch=getchar();
while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
return sum*p;
}
const int maxn=2e5+20;
int n,d,k;
bitset<120>a[maxn],b[maxn],c[maxn];
void init()
{
n=read();d=read();k=read();
}
int A[maxn],B[maxn],C[maxn],p[maxn],pp[maxn];
inline bool cmp(const int a,const int b)
{
if(A[a]==A[b])return B[a]==B[b]?C[a]<C[b]:B[a]<B[b];else return A[a]<A[b];
}
int v[1<<20];
inline int count(int a)
{
return v[a & (1<<16)-1]+v[a>>16];
}
void doing()
{
REP(i,1,(1<<20)-1)v[i]=v[i>>1]+(i & 1);
if(k==2)
{
REP(i,1,n)REP(j,0,d-1)if(read() & 1)a[i].set(j);
REP(i,1,n-1)REP(j,i+1,n)if(!((a[i]|a[j]).count() & 1))
{
printf("%d %d\n",i,j);
exit(0);
}
}else
{
if(n<=10000)
{
REP(i,1,n)REP(j,0,d-1)
{
int x=read()%3;
if(x!=0)a[i].set(j);
if(x!=2)b[i].set(j);
if(x!=1)c[i].set(j);
}
REP(i,1,n-1)REP(j,i+1,n)
{
int x=((a[i] & a[j]).count()-2*((a[i] & b[i])&(a[j] & c[j])).count()-2*((a[j]&b[j])&(a[i]&c[i])).count());
if(x%3==0)
{
printf("%d %d\n",i,j);
exit(0);
}
}
}else
{
REP(i,1,n)REP(j,0,d-1)
{
int x=read()%3;
if(x!=0)A[i]|=1<<j;
if(x!=2)B[i]|=1<<j;
if(x!=1)C[i]|=1<<j;
}
REP(i,1,n)p[i]=i;
sort(p+1,p+n+1,cmp);
int tot=1;
pp[1]=p[1];
REP(i,2,n)
{
int u=p[i],v=pp[tot];
if(A[u]!=A[v] || B[u]!=B[v] || C[u]!=C[v])pp[++tot]=p[i];
else{
int x=count(A[u]&A[v]);
if(x%3==0)
{
if(u>v)swap(u,v);
printf("%d %d\n",u,v);
return;
}
}
}
REP(i,1,tot-1)REP(j,i+1,tot)
{
int u=pp[i],v=pp[j],x=(count(A[u]&A[v])-2*count((A[u]&B[u])&(A[v]&C[v]))-2*count((A[u]&C[u])&(A[v]&B[v])));
if(x%3==0)
{
if(u>v)swap(u,v);
printf("%d %d\n",u,v);
return;
}
}
}
}
puts("-1 -1");
}
int main()
{
init();
doing();
return 0;
}
【fake题解】[NOI2013]向量内积的更多相关文章
- [Noi2013]向量内积
来自FallDream的博客,未经允许,请勿转载,谢谢. 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: $\sum_{i=1 ...
- P1224 [NOI2013]向量内积
传送门 发现这个内积和矩乘有点像,考虑构造一个 $n$ 行 $m$ 列的矩阵 $A$,每一行都是一个题目给定的 $m$ 维向量 设 $B=AA^T$ ,其中 $A^T$ 为 $A$ 的转置矩阵,那么对 ...
- luogu P1224 [NOI2013]向量内积
传送门 挺有意思的一道题 暴力60就是枚举每个向量暴力check,随机选向量就能多骗一些分 然后两个向量内积要模\(k\)为\(0\),那么如果全部不为\(0\)就不合法.先考虑\(k=2\),对于向 ...
- 【uoj121】 NOI2013—向量内积
http://uoj.ac/problem/121 (题目链接) 题意 给出${n}$个${d}$维向量,问是否有两个不同的向量的内积是${k}$的倍数. Solution 又卡了一上午常数,我弃了T ...
- 3243: [Noi2013]向量内积 - BZOJ
Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知 ...
- bzoj 3243: [Noi2013]向量内积
Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知 ...
- BZOJ3243 [Noi2013]向量内积 【乱搞】
题目链接 BZOJ3243 题解 模数只有\(2\)或\(3\),可以大力讨论 如果模数为\(2\),乘积结果只有\(1\)或\(0\) 如果一个向量和前面所有向量乘积都为\(1\),那么其和前面向量 ...
- BZOJ3243/UOJ121 [Noi2013]向量内积
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ3243 NOI2013向量内积(随机化)
考虑奇技淫巧. 首先是k=2.对向量维护一个前缀和,每次将当前向量与前缀和点乘.如果点乘结果不等于i-1&1,说明当前向量至少和之前的某个向量的数量积是2的倍数,暴力找就可以了.当然等于i-1 ...
随机推荐
- UITextField使用的一些细节
UITextField使用的一些细节 这篇博文是我自己使用UITextField的一些总结,并没有太多营养,并会持续更新. 2014.9.15 ---------------------------- ...
- 汽车学习---汽车知识大全【all】
汽车驱动/发动机/大灯 侧方位停车和倒车入库技巧 手动挡车型 换档8大技巧 常见的掉头情况注意事项 最全的左转,右转,待转,掉头方法 开车技巧大汇总,尤其适合新手司机 汽车常识扫盲,不做“汽车小白”! ...
- python面向对象-封装and多态
python 接口类和抽象类 为什么讲封装之前要将这个东西? 我才不会说为什么 首先: python没有接口类这个概念!!!!!!!! 哈哈哈......神经病 python抽象类和接口类更接近于一种 ...
- XGBoost 输出特征重要性以及筛选特征
1.输出XGBoost特征的重要性 from matplotlib import pyplot pyplot.bar(range(len(model_XGB.feature_importances_) ...
- Language-Directed Hardware Design for Network Performance Monitoring——Marple
网络监控困难 1.仅仅通过去增加特定的监控功能到交换机是不能满足运营商不断变化的需求的.(交换机需要支持网络性能问题的表达语言) 2.他们缺乏对网络深处的性能问题进行本地化的可见性,间接推断网络问题的 ...
- 论文 ClickP4: Towards Modular Programming of P4 小结
当前P4存在的问题(ClickP4为解决的问题) 1.随着P4程序的规模和复杂性的增加,从零开始开发单片P4程序容易出错,需要相当多的时间和精力去解决,所以网络政策的多样性和动态性使得运营商为了满足要 ...
- 获取URL网页信息
static string GetHtml(string url) {string strHTML = ""; WebClient myWebClient = new WebCli ...
- CSS3 Transform变形理解与应用
CSS3 Transform变形理解与应用 Transform:对元素进行变形:Transition:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画.但只有两个关键贞.开 ...
- java一个字符串中出现次数最多的字符以及次数
学习了别人的方法,觉得挺巧妙的.就是每次取出字符串的第一个字符,将字符串中与第一个字符相同的字符全部删除掉,然后通过计算删除前后字符串的长度来确定该字符在字符串中出现的次数,最终比较出出现最多次的字符 ...
- python第一课——关于python的一些概念
day01(上午): 1.学习方法(建议): 1).不要依赖于我的视频,绝对不要晚上将视频全部在过一遍 2).上课不要记笔记,而且不要用纸质的笔记本去整理笔记 3).不要只看不敲,代码方面我们需要做到 ...