<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

      A. Odd Palindrome

      所有回文子串長度都是奇數等價于不存在長度為$2$的偶回文子串,即相鄰兩個字符都不同。

      #include<cstdio>
      #include<cstring>
      char a[1111111];int n,i;
      int main(){
      	scanf("%s",a+1);
      	n=strlen(a+1);
      	for(i=1;i<n;i++)if(a[i]==a[i+1])return puts("Or not."),0;
      	puts("Odd.");
      }
      

        

      B. Enlarging Enthusiasm

      注意到方案數不超過$(n-1)\times (n-1)!$,爆搜出所有可行方案即可,需要大量常數優化。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      const int N=15;
      int n,m,i,a[N],f[(1<<12)+5],ans;
      int cnt[(1<<12)+5];
      int w[N];
      void dfs(int S,int mx,int q,int x){
      	if(!S){
      		ans++;
      		return;
      	}
      	mx++;
      	if((S&-S)==S){
      		int j=f[S];
      		int nowq=mx-j>q?mx-j:q;
      		if(x>=nowq)ans++;
      		return;
      	}
      	int U=S;
      	while(U){
      		int i=U&-U,j=f[i];
      		int nowq=mx-j>q?mx-j:q;
      		if(x>=nowq)dfs(S^i,j+nowq,nowq,x-nowq);
      		U^=i;
      	}
      }
      void gao(int S,int mx,int q,int x){
      	if(!S){
      		ans++;
      		return;
      	}
      	mx++;
      	for(int U=S;U;U-=U&-U){
      		int i=U&-U;
      		if(i==(1<<(n-1)))continue;
      		int nowq=mx-f[i];
      		if(nowq<q)nowq=q;
      		if(x>=nowq)dfs(S^i,f[i]+nowq,nowq,x-nowq);
      	}
      }
      int main(){
      	scanf("%d%d",&n,&m);
      	
      	for(i=1;i<1<<n;i++)cnt[i]=cnt[i>>1]+(i&1);
      	for(w[0]=i=1;i<=n;i++)w[i]=w[i-1]*i;
      	
      	for(i=0;i<n;i++)scanf("%d",&a[i]);
      	sort(a,a+n);
      	for(i=0;i<n;i++)f[1<<i]=a[i];
      	gao((1<<n)-1,a[n-1],0,m);
      	printf("%d",ans);
      }
      /*
      12 700
      1 2 3 4 5 6 7 8 9 10 11 12
      */
      

        

      C. Fear Factoring

      考慮每個約數的貢獻,那么分段等差數列求和即可。

      時間復雜度$O(\sqrt{b})$。

      #include<cstdio>
      typedef long long ll;
      ll cal(ll n){
      	ll i,j;
      	ll ans=0;
      	for(i=1;i<=n;i=j+1){
      		j=n/(n/i);
      		ans+=(i+j)*(j-i+1)*(n/i);
      	}
      	return ans;
      }
      int main(){
      	ll a,b;
      	scanf("%lld%lld",&a,&b);
      	printf("%lld",(cal(b)-cal(a-1))/2);
      }
      

        

      D. Rainbow Roads

      對于每個點,若其有超過一條同色的邊,那么對應子樹都不是Good點,差分前綴和打標記即可。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      typedef pair<int,int>P;
      const int N=300010;
      int n,i,j,k,x,y,z,g[N],v[N],w[N],nxt[N],ed;
      int f[N],dfn,st[N],en[N];
      int m,ans,s[N];
      P q[N];
      inline void add(int x,int y,int z){
      	v[++ed]=y;
      	w[ed]=z;
      	nxt[ed]=g[x];
      	g[x]=ed;
      }
      void dfs(int x,int y){
      	st[x]=++dfn;
      	f[x]=y;
      	for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x);
      	en[x]=dfn;
      }
      int main(){
      	scanf("%d",&n);
      	for(i=1;i<n;i++){
      		scanf("%d%d%d",&x,&y,&z);
      		add(x,y,z),add(y,x,z);
      	}
      	dfs(1,0);
      	for(i=1;i<=n;i++){
      		m=0;
      		for(j=g[i];j;j=nxt[j])q[++m]=P(w[j],v[j]);
      		sort(q+1,q+m+1);
      		for(j=1;j<=m;j=k){
      			for(k=j;k<=m&&q[j].first==q[k].first;k++);
      			if(k>j+1){
      				for(x=j;x<k;x++){
      					y=q[x].second;
      					if(y==f[i]){
      						s[1]++;
      						s[st[i]]--;
      						s[en[i]+1]++;
      					}else{
      						s[st[y]]++;
      						s[en[y]+1]--;
      					}
      				}
      			}
      		}
      	}
      	for(i=1;i<=n;i++)s[i]+=s[i-1];
      	for(i=1;i<=n;i++)if(!s[st[i]])ans++;
      	printf("%d\n",ans);
      	for(i=1;i<=n;i++)if(!s[st[i]])printf("%d\n",i);
      }
      

        

      E. Straight Shot

      二分水平分速度,檢查最終是否走到了$(x,0)$。

      #include<cstdio>
      #include<cmath>
      #include<algorithm>
      using namespace std;
      const int N=111;
      int n,i;
      double X,V,dx,dy;
      double lim,goal=1e100,tmp,L,R,MID,l[N],r[N],v[N];
      double cal(double dy){
      	double dx=sqrt(V*V-dy*dy);
      	double x=0,y=0;
      	for(int i=1;i<=n;i++){
      		y+=dy*(l[i]-x);
      		y+=(dy+v[i])*(r[i]-l[i]);
      		x=r[i];
      	}
      	y+=dy*(X-x);
      	tmp=X/dx;
      	return y/dx;
      }
      int main(){
      	scanf("%d%lf%lf",&n,&X,&V);
      	for(i=1;i<=n;i++)scanf("%lf%lf%lf",&l[i],&r[i],&v[i]);
      	L=-V,R=V;
      	for(int _=1000;_;_--){
      		MID=(L+R)/2;
      		if(cal(MID)<0)L=MID;else R=MID;
      	}
      	lim=X/V*2;
      	L=(L+R)/2;
      	if(fabs(cal(L))<1e-8){
      		cal(L);
      		goal=tmp;
      	}
      	if(goal>lim+1e-8)puts("Too hard");
      	else printf("%.3f",goal);
      }
      

        

      F. Distinct Distances

      答案點只可能取在每個點、兩個點的中點,以及兩對點垂直平分線的交點。

      #include<cstdio>
      #include<cmath>
      #include<algorithm>
      using namespace std;
      const int N=50;
      const double eps=1e-9;
      inline int sgn(double x){
      	if(x>eps)return 1;
      	if(x<-eps)return -1;
      	return 0;
      }
      struct P{
      	double x,y;
      	P(){}
      	P(double _x,double _y){x=_x,y=_y;}
      	P operator+(P b){return P(x+b.x,y+b.y);}
      	P operator-(P b){return P(x-b.x,y-b.y);}
      	P operator*(double b){return P(x*b,y*b);}
      	P operator/(double b){return P(x/b,y/b);}
      	void read(){scanf("%lf%lf",&x,&y);}
      	double len(){return x*x+y*y;}
      	double dis(const P&b){return (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y);}
      	bool operator==(P b){return !sgn(x-b.x)&&!sgn(y-b.y);}
      	P rot90(){return P(-y,x);}
      }a[N],e[N*N][2];
      int n,m,i,j,ans=N;
      double d[N];
      inline void solve(P O){
      	//printf("%.10f %.10f\n",O.x,O.y);
      	int i;
      	for(i=1;i<=n;i++)d[i]=O.dis(a[i]);
      	sort(d+1,d+n+1);
      	int t=1;
      	for(i=2;i<=n&&t<ans;i++)if(d[i]>d[i-1]+eps)t++;
      	if(t<ans)ans=t;
      }
      inline void makeline(P a,P b){
      	if(a==b)return;
      	P c=(a+b)/2.0;
      	solve(c);
      	b=b-a;
      	e[++m][0]=c;
      	e[m][1]=c+b.rot90();
      	//printf("%.5f %.5f %.5f %.5f\n",e[m][0].x,e[m][0].y,e[m][1].x,e[m][1].y);
      }
      inline double cross(P a,P b){
      	return a.x*b.y-a.y*b.x;
      }
      inline void gao(P a,P b,P p,P q){
      	double U=cross(p-a,q-p),D=cross(b-a,q-p);
      	if(!sgn(D))return;
      	//puts("!");
      	solve(a+(b-a)*(U/D));
      }
      int main(){
      	scanf("%d",&n);
      	for(i=1;i<=n;i++)a[i].read();
      	for(i=1;i<=n;i++)solve(a[i]);
      	for(i=1;i<=n;i++)for(j=1;j<i;j++){
      		makeline(a[i],a[j]);
      	}
      	//makeline(a[4],a[5]);
      	//makeline(a[5],a[1]);
      	for(i=1;i<=m;i++)for(j=1;j<i;j++)gao(e[i][0],e[i][1],e[j][0],e[j][1]);
      	printf("%d",ans);
      }
      /*
      6
      0 -5
      1 0
      -1 0
      2 3
      3 2
      -3 0
      */
      

        

      G. Security Badge

      對區間離散化,那么只需要檢查$O(m)$個人是否可行,每次暴力Floodfill判斷即可。

      時間復雜度$O(m(n+m))$。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      const int N=10010;
      int n,m,k,S,T,i,j,cnt,q[N],K;
      int g[N],ed,v[N],vc[N],vd[N],nxt[N],vis[N],ans;
      inline void add(int x,int y,int c,int d){
      	v[++ed]=y;
      	vc[ed]=c;
      	vd[ed]=d;
      	nxt[ed]=g[x];
      	g[x]=ed;
      }
      void dfs(int x){
      	if(vis[x])return;
      	vis[x]=1;
      	for(int i=g[x];i;i=nxt[i])if(vc[i]<=K&&K<=vd[i])dfs(v[i]);
      }
      int main(){
      	scanf("%d%d%d%d%d",&n,&m,&k,&S,&T);
      	for(i=1;i<=m;i++){
      		int a,b,c,d;
      		scanf("%d%d%d%d",&a,&b,&c,&d);
      		add(a,b,c,d);
      		q[++cnt]=c-1;
      		q[++cnt]=d;
      	}
      	sort(q+1,q+cnt+1);
      	for(i=2;i<=cnt;i++)if(q[i]!=q[i-1]){
      		K=q[i];
      		for(j=1;j<=n;j++)vis[j]=0;
      		dfs(S);
      		if(vis[T])ans+=q[i]-q[i-1];
      	}
      	printf("%d",ans);
      }
      

        

      H. Avoiding Airports

      將每架飛機拆成上飛機和下飛機兩個事件,并按照時間順序依次考慮。

      設$dp[x]$表示最后乘坐第$x$架飛機的最小代價,那么轉移是經典斜率優化形式,對于每個點用單調隊列維護凸殼即可。

      時間復雜度$O(m\log m)$。

      #include<cstdio>
      #include<algorithm>
      #include<vector>
      using namespace std;
      typedef long long ll;
      const int N=200010;
      const ll inf=1LL<<60;
      int n,m,i,e[N][4],cnt;
      struct E{
      	int x,y;
      	E(){}
      	E(int _x,int _y){x=_x,y=_y;}
      }w[N<<1];
      ll dp[N],ans=inf;
      struct Line{
      	ll k,b;
      	Line(){}
      	Line(ll _k,ll _b){k=_k,b=_b;}
      	ll f(ll x){return k*x+b;}
      };
      vector<Line>g[N];
      int head[N],tail[N],deg[N];
      inline bool cmp(const E&a,const E&b){
      	if(a.x!=b.x)return a.x<b.x;
      	return a.y<b.y;
      }
      inline double pos(const Line&a,const Line&b){
      	return 1.0*(a.b-b.b)/(b.k-a.k);
      }
      inline void ins(int o,ll k,ll b){
      	if(b>=inf)return;
      	Line now(k,b);
      	int&h=head[o],&t=tail[o];
      	if(h<=t){
      		if(g[o][t].k==k){
      			if(g[o][t].b<=b)return;
      			t--;
      		}
      	}
      	while(h<t&&pos(g[o][t-1],g[o][t])>=pos(g[o][t],now))t--;
      	g[o][++t]=now;
      }
      inline ll cal(int o,ll x){
      	int&h=head[o],&t=tail[o];
      	if(h>t)return inf;
      	while(h<t&&g[o][h].f(x)>g[o][h+1].f(x))h++;
      	return g[o][h].f(x);
      }
      int main(){
      	scanf("%d%d",&n,&m);
      	for(i=1;i<=m;i++){
      		scanf("%d%d%d%d",&e[i][0],&e[i][1],&e[i][2],&e[i][3]);
      		deg[e[i][1]]++;
      		w[++cnt]=E(e[i][2],-i);//s
      		w[++cnt]=E(e[i][3],i);//e
      	}
      	sort(w+1,w+cnt+1,cmp);
      	deg[1]++;
      	for(i=1;i<=n;i++)tail[i]=-1,g[i].resize(deg[i]+2);
      	ins(1,0,0);//kx+b
      	for(i=1;i<=cnt;i++){
      		int x=w[i].y;
      		//printf("->%d %d\n",w[i].x,x);
      		if(x<0){
      			int y=-x;
      			dp[y]=cal(e[y][0],e[y][2]);
      			if(dp[y]<inf)dp[y]+=1LL*e[y][2]*e[y][2];
      			//printf("! %d %lld\n",y,dp[y]);
      		}else{
      			//printf("ins %d %lld\n",e[x][1],dp[x]);
      			ins(e[x][1],-2LL*e[x][3],dp[x]+1LL*e[x][3]*e[x][3]);
      		}
      	}
      	for(i=1;i<=m;i++)if(e[i][1]==n)ans=min(ans,dp[i]);
      	printf("%lld",ans);
      }
      /*
      3 5
      1 1 10 20
      1 2 30 40
      1 2 50 60
      1 2 70 80
      2 3 90 95
      
      
      5 8
      1 2 1 10
      2 4 11 16
      2 1 9 12
      3 5 28 100
      1 2 3 8
      4 3 20 21
      1 3 13 27
      3 5 23 24
      */
      

        

      I. Long Long Strings

      初始串取字符集無窮的超長字符串是最壞情況,壓縮區間后暴力操作即可。

      #include<stdio.h>
      #include<iostream>
      #include<string.h>
      #include<string>
      #include<ctype.h>
      #include<math.h>
      #include<set>
      #include<map>
      #include<vector>
      #include<queue>
      #include<bitset>
      #include<algorithm>
      #include<time.h>
      using namespace std;
      void fre() {  }
      #define MS(x, y) memset(x, y, sizeof(x))
      #define ls o<<1
      #define rs o<<1|1
      typedef long long LL;
      typedef unsigned long long UL;
      typedef unsigned int UI;
      template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
      template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
      const int N = 0, M = 0, Z = 1e9 + 7;
      template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
      int casenum, casei;
      int n;
      const LL inf = 1e12;
      struct A
      {
      	LL st;
      	LL ed;
      	LL stval;
      	bool operator < (const A &b)const
      	{
      		return st < b.st;
      	}
      };
      set<A>sot1, sot2;
      void doit(set<A> &sot)
      {
      	char ch;
      	while(~scanf(" %c", &ch))
      	{
      		if(ch == 'D')
      		{
      			LL pos;
      			scanf("%lld", &pos);
      			auto it = --sot.upper_bound({pos});
      			LL st = it->st;
      			LL ed = it->ed;
      			LL stval = it->stval;
      			sot.erase(it);
      			vector<A>vt;
      			if(st <= pos - 1)
      			{
      				vt.push_back({st, pos - 1, stval});
      			}
      			if(pos + 1 <= ed)
      			{
      				vt.push_back({pos, ed - 1, stval + pos + 1 - st});
      			}
      			for(auto w=sot.lower_bound({pos + 1}),nxt = w;w!= sot.end();w=nxt)
      			{
      				nxt = w; ++nxt;
      				vt.push_back({w->st - 1, w->ed - 1, w->stval});
      				sot.erase(w);
      			}
      			for(auto it : vt)sot.insert(it);
      		}
      		else if(ch == 'I')
      		{
      			char val_;
      			LL pos, val;
      			scanf("%lld %c", &pos, &val_);
      			val = inf + val_;
      			auto it = --sot.upper_bound({pos});
      			LL st = it->st;
      			LL ed = it->ed;
      			LL stval = it->stval;
      			sot.erase(it);
      			vector<A>vt;
      			if(st <= pos - 1)
      			{
      				vt.push_back({st, pos - 1, stval});
      			}
      			if(pos <= ed)
      			{
      				vt.push_back({pos + 1, ed + 1, stval + pos - st});
      			}
      			for(auto w=sot.lower_bound({pos + 1}),nxt = w;w!= sot.end();w=nxt)
      			{
      				nxt = w; ++nxt;
      				vt.push_back({w->st + 1, w->ed + 1, w->stval});
      				sot.erase(w);
      			}
      			vt.push_back({pos, pos, val});
      			for(auto it : vt)sot.insert(it);
      		}
      		else break;
      		/*
      		for(auto it : sot)
      		{
      			printf("%lld %lld %lld\n", it.st, it.ed, it.stval);
      		}
      		puts("show end");
      		*/
      	}	
      }
      bool check()
      {
      	LL ed1 = (--sot1.end())->ed;
      	LL ed2 = (--sot1.end())->ed;
      	if(ed1 != ed2)return 0;
      	LL now = 1;
      	while(now <= ed1)
      	{
      		auto it1 = sot1.begin();
      		auto it2 = sot2.begin();
      		LL ed1 = it1->ed;
      		LL ed2 = it2->ed;
      		if(it1->stval != it2->stval)return 0;
      		LL stval = it1->stval;
      		LL nxt = min(it1->ed, it2->ed) + 1;
      		sot1.erase(it1);
      		sot2.erase(it2);
      		if(nxt <= ed1)
      		{
      			sot1.insert({nxt, ed1, nxt - now + stval});
      		}
      		if(nxt <= ed2)
      		{
      			sot2.insert({nxt, ed2, nxt - now + stval});
      		}
      		now = nxt;
      	}
      	return 1;
      }
      int main()
      {
      	sot1.clear();
      	sot1.insert({1, inf, 1});
      	sot2.clear();
      	sot2.insert({1, inf, 1});
      	doit(sot1);
      	doit(sot2);
      	/*
      	for(auto it : sot1)
      	{
      		printf("%lld %lld %lld\n", it.st, it.ed, it.stval);
      	}
      	puts("-------------");
      	for(auto it : sot2)
      	{
      		printf("%lld %lld %lld\n", it.st, it.ed, it.stval);
      	}
      	*/
      	puts(check() ? "0" : "1");
      	return 0;
      }
      /*
      【trick&&吐槽】
      
      
      【題意】
      
      
      【分析】
      
      
      【時間復雜度&&優化】
      
      
      */
      

        

      J. Grid Coloring

      設$f[i][j]$表示考慮前$i$行,第$i$行前$j$個都是藍色,后面都是紅色的方案數,暴力轉移即可。

      時間復雜度$O(n^3)$。

      #include<cstdio>
      typedef long long ll;
      const int N=40;
      int n,m,i,j,k;
      ll ans,f[N][N];
      char a[N][N];
      bool can[N][N];
      inline bool check(int x,int y){
      	for(int i=1;i<=y;i++)if(a[x][i]=='R')return 0;
      	for(int i=y+1;i<=m;i++)if(a[x][i]=='B')return 0;
      	return 1;
      }
      int main(){
      	scanf("%d%d",&n,&m);
      	for(i=1;i<=n;i++)scanf("%s",a[i]+1);
      	for(i=1;i<=n;i++){
      		for(j=0;j<=m;j++){
      			can[i][j]=check(i,j);
      		}
      	}
      	//f[i][j] [1..j] is B, j+1..m is R
      	for(j=0;j<=m;j++)f[1][j]=can[1][j];
      	for(i=1;i<n;i++)for(j=0;j<=m;j++)for(k=0;k<=j;k++)f[i+1][k]+=f[i][j]*can[i+1][k];
      	for(j=0;j<=m;j++)ans+=f[n][j];
      	printf("%lld",ans);
      }
      

        

      K. Spinning Up Palindromes

      顯然最優解中一定是從右往左操作,故問題可以轉化成:給定數字$A$,找到一個數位和最小的數字$B$,使得$A+B$是回文串。

      考慮從兩邊往中間DP,設$f[i][j][k]$表示考慮前后$i$個位置,前面希望后面進位為$j$,后面對前面進位為$k$的最小代價。

      #include<cstdio>
      #include<cstring>
      const int N=50,inf=10000000;
      int n,m,l,r,i,j,k,x,y,t,w;
      char s[N];
      int a[N],f[N][2][2],ans=inf;
      inline void up(int&a,int b){a>b?(a=b):0;}
      int main(){
      	scanf("%s",s+1);
      	n=strlen(s+1);
      	for(i=1;i<=n;i++)a[i]=s[i]-'0';
      	for(i=0;i<=n+5;i++)for(j=0;j<2;j++)for(k=0;k<2;k++)f[i][j][k]=inf;
      	f[0][0][0]=f[0][1][0]=0;
      	for(l=1,r=n;l<r;l++,r--)for(i=0;i<2;i++)for(j=0;j<2;j++)if(f[l-1][i][j]<inf){
      		w=f[l-1][i][j];
      		for(x=0;x<10;x++)for(y=0;y<10;y++){//what is b
      			for(k=0;k<2;k++){//jinwei from l+1
      				int A=a[l]+x+k,nA=0;
      				if(A>=10)A-=10,nA++;
      				if(nA!=i)continue;
      				int B=a[r]+y+j,nB=0;
      				if(B>=10)B-=10,nB++;
      				if(A!=B)continue;
      				up(f[l][k][nB],w+x+y);
      			}
      		}
      	}
      	m=n/2;
      	if(n%2){
      		for(i=0;i<2;i++)for(j=0;j<2;j++)if(f[m][i][j]<inf){
      			w=f[m][i][j];
      			for(x=0;x<10;x++){
      				if((a[m+1]+x+j)/10!=i)continue;
      				up(ans,w+x);
      			}
      		}
      	}else{
      		for(i=0;i<2;i++)for(j=0;j<2;j++)if(f[m][i][j]<inf){
      			w=f[m][i][j];
      			if(i==j)up(ans,w);
      		}
      	}
      	printf("%d",ans);
      }
      

        

      L. Delayed Work

      暴力枚舉人數即可。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      typedef long long ll;
      ll K,P,X,i;double ans;
      int main(){
      	scanf("%lld%lld%lld",&K,&P,&X);
      	ans=1e20;
      	for(i=1;i<=3000000;i++){
      		ans=min(ans,1.0*K*P/i+1.0*X*i);
      	}
      	printf("%.3f",ans);
      }
      

        

      M. Unsatisfying

      若初始2-SAT無解,那么答案顯然為$0$。

      如果不存在$\neg x\lor\neg y$,那么無解。

      否則枚舉每個$x$,強行規定$x=true$,若2-SAT無解則答案為$1$。

      否則答案只能為$2$。

      時間復雜度$O(n(n+m))$。

      #include<stdio.h>
      #include<iostream>
      #include<string.h>
      #include<string>
      #include<ctype.h>
      #include<math.h>
      #include<set>
      #include<map>
      #include<vector>
      #include<queue>
      #include<bitset>
      #include<algorithm>
      #include<time.h>
      using namespace std;
      void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
      #define MS(x, y) memset(x, y, sizeof(x))
      #define ls o<<1
      #define rs o<<1|1
      typedef long long LL;
      typedef unsigned long long UL;
      typedef unsigned int UI;
      template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
      template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
      const int N = 4010, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
      template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
      int casenum, casei;
      
      
      int n, m, nn;
      int x, y;
      vector<int> a[N];
      bool pick[N];
      int sta[N], top;
      bool dfs(int x)
      {
      	if(pick[x ^ 1]) return 0;
      	if(pick[x]) return 1;
      	pick[x] = 1;
      	sta[++ top] = x;
      	for(int i = a[x].size() - 1; ~ i; -- i){
      		int y = a[x][i];
      		if(!dfs(y)) return 0;
      	}
      	return 1;
      }
      bool solve()
      {
      	for(int i = 0; i < nn; i += 2) if(!pick[i] && !pick[i ^ 1]){
      		top = 0;
      		if(!dfs(i)){
      			while(top) pick[sta[top --]] = 0;
      			top = 0;
      			if(!dfs(i ^ 1)) return 0;
      		}
      	}
      	return 1;
      }
      
      int main()
      {
      	scanf("%d%d", &n, &m);
      	int flag = 0;
      	nn = n * 2;
      	for(int i = 0; i < nn; i ++) pick[i] = 0, a[i].clear();
      	for(int i = 1; i <= m; i ++){
      		scanf("%d%d", &x, &y);
      		int xx = abs(x), yy = abs(y);
      		xx *= 2; yy *= 2;
      		xx --; yy --;
      		if(x < 0 && y < 0) flag = 1;
      		if(x < 0 && y < 0){
      			a[xx].push_back(yy ^ 1);
      			a[yy].push_back(xx ^ 1);
      			//printf("%d %d\n", xx, yy ^ 1);
      			//printf("%d %d\n", yy, xx ^ 1);
      			
      		}
      		else if(x < 0 && y > 0){
      			a[xx].push_back(yy);
      			a[yy ^ 1].push_back(xx ^ 1);
      			//printf("%d %d\n", xx, yy);
      			//printf("%d %d\n", yy ^ 1, xx ^ 1);
      			
      		}
      		else if(x > 0 && y < 0){
      			a[yy].push_back(xx);
      			a[xx ^ 1].push_back(yy ^ 1);
      			//printf("%d %d\n", yy, xx);
      			//printf("%d %d\n", xx ^ 1, yy ^ 1);
      			
      		}
      		else if(x > 0 && y > 0){
      			a[xx ^ 1].push_back(yy);
      			a[yy ^ 1].push_back(xx);
      			//printf("%d %d\n", xx ^ 1, yy);
      			//printf("%d %d\n", yy ^ 1, xx);
      			
      		}
      	}
      	if(!flag){puts("-1"); return 0;}
      	if(!solve()) {puts("0"); return 0;}
      	for(int i = 1; i <= n; i ++){
      		for(int j = 0; j < nn; j ++){
      			//a[i].clear();
      			pick[j] = 0;
      		}
      		int xx = i * 2 - 1;	
      		//a[xx].push_back(xx ^ 1);
      		a[xx ^ 1].push_back(xx);
      		
      		if(!solve()){
      			puts("1"); return 0;
      		}
      		//a[xx].pop_back();
      		a[xx ^ 1].pop_back();
      	}
      	puts("2");
      	return 0;
      }
      /*
      【trick&&吐槽】
      
      
      【題意】
      
      4 5
      1 2
      0 3
      2 1
      -1 -3
      1 4
      5 0
      -2 3
      3 5
      4 2
      3 -4
      7 5
      4 6
      -2 -3
      3 4
      5 2
      0
      
      【分析】
      
      
      【時間復雜度&&優化】
      
      
      */
      

        

      posted @ 2017-11-15 23:58  Claris  閱讀(2177)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 久久国产精品日本波多野结衣 | 亚洲人成小说网站色在线| 国产成人一区二区视频免费| 国产95在线 | 欧美| 无码视频一区二区三区| 国产精品一二三区蜜臀av| 亚洲综合色成在线播放| 亚洲gv天堂无码男同在线观看| 台北市| 亚洲精品国产av成人网| 亚洲精品日韩在线丰满| 欧美不卡无线在线一二三区观 | 成人亚欧欧美激情在线观看| 午夜激情小视频一区二区| 99999久久久久久亚洲| 在线视频一区二区三区色| 思思99热精品在线| 亚洲无人区一码二码三码| 东丽区| 欧美丰满熟妇xxxx性| 永久无码天堂网小说区| 亚洲精品天堂在线观看| 蜜臀av入口一区二区三区| 国产在线视频www色| 国产免费性感美女被插视频| 国内精品免费久久久久电影院97| 日本一区二区三区免费播放视频站| 国产亚洲综合另类色专区| 另类 专区 欧美 制服丝袜| 国产欧美精品一区aⅴ影院| 国产69久久精品成人看| 久久精产国品一二三产品| 国语精品自产拍在线观看网站| 国产不卡一区二区在线| 91福利视频一区二区| 成全高清在线播放电视剧| 樱桃熟了a级毛片| 国产女人18毛片水真多1| 一区二区三区四区五区自拍| 免费视频欧美无人区码| 国产成人精品一区二三区|