【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 ...
随机推荐
- 转: SSH框架总结(框架分析+环境搭建+实例源码下载)
原:http://blog.csdn.net/shan9liang/article/details/8803989 首先,SSH不是一个框架,而是多个框架(struts+spring+hibernat ...
- 使用FBTweak
使用FBTweak https://github.com/facebook/Tweaks FBTweak是Facebook的一款开源库,用于微调数据而无需我们重复编译跑真机用的,它支持4种类型的cel ...
- November 7th 2016 Week 46th Monday
A friend is one who knows you and loves you just the same. 朋友是懂你并爱你的人. Friendship means inclusion, l ...
- D:\hunting2014\小题目\字符串倒序
#include<stdio.h>#include<string.h> char *revert(char *str){ char temp; char *p = str; c ...
- Android 高级UI设计笔记23:Android 夜间模式之 两种常用方法(降低屏幕亮度+替换theme)
1. 夜间模式 所谓的夜间模式,就是能够根据不同的设定,呈现不同风格的界面给用户,而且晚上看着不伤眼睛.特别是一些新闻类App实现夜间模式是非常人性化的,增强用户体验. 2. 我根据网上的资料 以及自 ...
- mongodb的学习-2-简介
http://www.runoob.com/mongodb/mongodb-intro.html 什么是MongoDB ? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系 ...
- Python spli指定多个分隔符
#!/usr/bin/python # -*- coding: UTF-8 -*- import re a='Beautiful, is; better*than\nugly' 以竖线"|& ...
- find 的一些用法
find的一些用法 例1:find . -type f -exec chmod -R 644 {} \ ; #{}代表签名的输出,\;代表结束命令操作结束 例2: find -print0 |xa ...
- C#中控件Control的Paint事件和OnPaint虚函数的区别
句柄 : 句柄,是整个Windows编程的基础.一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按 ...
- 适合自己的adblock过滤列表
轻微完美主义,极简主义 已屏蔽广告: 1.CSDN的广告 2.百度侧栏热点搜索 3. 知乎广告 4.stackoverflow的推送广告 5.LeetCode的推送的是否见过这个题 bbs.csdn. ...