石家庄做淘宝网站,长春互联网公司哪里多,网站备案 太烦,上海app制作公司传送门 文章目录题意#xff1a;思路#xff1a;题意#xff1a;
构造一个图#xff0c;使其从111到nnn的路径的长度与[L,R][L,R][L,R]中某个值一一对应#xff0c;不能有两条路径长度一样#xff0c;且每个值都必须出现一次#xff0c;每两个点之间只能连一条边。 n≤…传送门
文章目录题意思路题意
构造一个图使其从111到nnn的路径的长度与[L,R][L,R][L,R]中某个值一一对应不能有两条路径长度一样且每个值都必须出现一次每两个点之间只能连一条边。 n≤32n\le32n≤32ai,bi≤na_i,b_i\le nai,bi≤n1≤ci≤1e61\le c_i\le 1e61≤ci≤1e6。
思路
看到n≤32n\le 32n≤32不难想到二进制拆分我们分情况来讨论。 (1)L1,R2k(1)\ \ L1,R2^k(1) L1,R2k 对于这种情况我们需要拿出来k2k2k2个点从111向[2,k2][2,k2][2,k2]的点连边权为111的边让后对于后面的每一个位置iii都向后连边权为2i−22^{i-2}2i−2的边这样就可以构造出[1,2k][1,2^k][1,2k]内的边权了。 (2)L1,R1(2)\ \ L1,R1(2) L1,R1 对于这种情况我们依旧按照(1)(1)(1)的思路构造出[1,2k][1,2^k][1,2k]的边权让后再新加一个点k3k3k3考虑用新的点来构造出来[2k1,R][2^k1,R][2k1,R]的边权。 对于RRR他的二进制形式大概是这样的100100100...100100100...100100100...很明显我们可以根据111来分段因为我们已经构造出来了[1,2i][1,2^i][1,2i]即[1,1000..][1,1000..][1,1000..]假设RRR的从低位到高位的第iii位(从000开始)是111那么我们只需要从i2i2i2的位置向k3k3k3连一个RRR将iii位及其之后的数都变成000的边权但是这样会有点问题就是因为构造的是[1,2i][1,2^i][1,2i]缺少000那么连完之后也就缺少后面全000的边权。所以我们考虑将R−1R-1R−1之后建边在新边的边权都111即可。 (3)L1,R1(3)\ \ L1,R1(3) L1,R1 只需要在最后新加一个点在原来的最后一个点向他连l−1l-1l−1的边即可转化成情况(1)(1)(1)或(2)(2)(2)。
//#pragma GCC optimize(Ofast,no-stack-protector,unroll-loops,fast-math)
//#pragma GCC target(sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tunenative)
//#pragma GCC optimize(2)
#includecstdio
#includeiostream
#includestring
#includecstring
#includemap
#includecmath
#includecctype
#includevector
#includeset
#includequeue
#includealgorithm
#includesstream
#includectime
#includecstdlib
#define X first
#define Y second
#define L (u1)
#define R (u1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].ltr[u].r1)
#define Len(u) (tr[u].r-tr[u].l1)
#define random(a,b) ((a)rand()%((b)-(a)1))
#define db puts(---)
using namespace std;//void rd_cre() { freopen(d://dp//data.txt,w,stdout); srand(time(NULL)); }
//void rd_ac() { freopen(d://dp//data.txt,r,stdin); freopen(d://dp//AC.txt,w,stdout); }
//void rd_wa() { freopen(d://dp//data.txt,r,stdin); freopen(d://dp//WA.txt,w,stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pairint,int PII;const int N1000010,mod1e97,INF0x3f3f3f3f;
const double eps1e-6;int l,r;
int tot;
struct Node
{int a,b,w;
}edge[N];void add(int a,int b,int c)
{edge[tot]{a,b,c};
}int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cinlr;puts(YES);int rrr-l1;int k0;while((1k)rr) k;if((1k)r){int cntk2;for(int i2;ik2;i) add(1,i,1);for(int i2;ik2;i)for(int ji1;jk2;j)add(i,j,1(i-2));if(l1) add(cnt,cnt1,l-1),cnt;printf(%d %d\n,cnt,tot);for(int i1;itot;i) printf(%d %d %d\n,edge[i].a,edge[i].b,edge[i].w);}else {k--;int cntk3;for(int i2;ik2;i) add(1,i,1);for(int i2;ik2;i)for(int ji1;jk2;j)add(i,j,1(i-2));add(1,k3,1);for(int i0;ik;i)if((rr-1)i1)add(i2,k3,((rr-1)(i1)(i1))1);if(l1) add(cnt,cnt1,l-1),cnt;printf(%d %d\n,cnt,tot);for(int i1;itot;i) printf(%d %d %d\n,edge[i].a,edge[i].b,edge[i].w);}return 0;
}
/**/