Codeforces Round #107 (Div. 2)

比賽地址:http://codeforces.com/contest/151

A:簡單題。

B:模擬題。

C:看p分解成素數的個數

假設p分解爲 p=p1^a1*p2^a2*p3^a3****pn^an.

令 sum=a1+a2+a3..+an.

 (1)sum>=3  1贏,任意輸出兩個素因子的乘積。

 (2)sum==2    2贏,

 (3)sum==1    1贏,輸出0

 

D:dfs.把必須相同的兩個數的位置連接起來,然後dfs一遍就行了,找出共有num個不同的位置,結果就是 m^num ,注意ans要用64位。

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <vector>
using namespace std;

const int maxn = 2005;
const int MOD = 1000000007;
int n,m,k;
vector<int>v[maxn];
int vis[maxn];

void dfs(int t)
{
   vis[t]=1;
   for(int i=0;i<v[t].size();i++)
   {
	   if(vis[v[t][i]]==1)
		   continue;
	   dfs(v[t][i]);
   }
   return ;
}

int main()
{
    while(scanf("%d %d %d",&n,&m,&k)!=EOF)
	{
        for(int i=0;i<n;i++)
		{
			v[i].clear();
			vis[i]=0;
		}

		for(int i=0;i<n-k+1;i++)
           for(int j=i,t=i+k-1;j<i+k;j++,t--)
               v[j].push_back(t);

		int num=0;
        for(int i=0;i<n;i++)
		{
           if(vis[i]==1)
			   continue;
		   num+=1;
		   dfs(i);
		}
		
		__int64 ans=1;
		for(int i=1;i<=num;i++)
			ans=ans*m%MOD;
		printf("%I64d\n",ans);
	}
	return 0;
}


E:Smart  Cheater   節點值出現負值的線段樹,

我們可以先求出每兩個車站之間的期望利潤爲 (x[i+1]-x[i])/2-pi*c;m個人是獨立的,可以轉化爲求一段

區間的最大連續和,節點值可能爲負值,有m個詢問。注意這裏的樹節點的值可能出現負值,所以我們

在查詢函數Find_max()返回一個節點,這個節點值ans記錄這個區間[l,r]的最大值,最大坐連續值,最

大右連續值,而且這些最大值都是在區間[l,r]取得的。保證了不超出範圍。

具體見SegTree Find_max(int t,int l,int r)函數。

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <vector>
using namespace std;

const int maxn = 150005;
const double inf = 1e30;
int n,m,c;
int x[maxn];
int p[maxn];
double s[maxn];
double sum[maxn];

struct SegTree
{
	int l;
	int r;
	double max_l;
	double max_r;
	double max_s;
	double sum;
}T[maxn*4+1];


void Build(int t,int l,int r)
{
	T[t].l=l;
	T[t].r=r;
	T[t].max_l=-inf;
	T[t].max_r=-inf;
	T[t].max_s=-inf;
	T[t].sum=0;
	if(T[t].l<T[t].r-1)
	{
		int mid=(T[t].l+T[t].r)/2;
		Build(2*t,T[t].l,mid);
		Build(2*t+1,mid,T[t].r);
	}
    return ;
}

void Adjust(int t,int l,int r)
{
   if(T[t].l==T[t].r-1)
   {
	   T[t].max_l=s[T[t].l];
	   T[t].max_r=s[T[t].l];
       T[t].max_s=s[T[t].l];
	   T[t].sum=s[T[t].l];
	   return ;
   }
   int mid=(l+r)/2;
   Adjust(2*t,l,mid);
   Adjust(2*t+1,mid,r);
   T[t].sum=T[2*t].sum+T[2*t+1].sum;
   T[t].max_l=max(T[2*t].max_l,T[2*t].sum+T[2*t+1].max_l);
   T[t].max_r=max(T[2*t+1].max_r,T[2*t+1].sum+T[2*t].max_r);
   T[t].max_s=max(max(T[t].max_l,T[t].max_r),max(T[2*t].max_s,T[2*t+1].max_s));
   T[t].max_s=max(T[t].max_s,T[2*t].max_r+T[2*t+1].max_l);
   return ;
}

SegTree Find_max(int t,int l,int r)
{
   if(T[t].l==l && T[t].r==r)
	   return T[t];
   int mid=(T[t].l+T[t].r)/2;
   if(r<=mid)
	   return Find_max(2*t,l,r);
   else if(l>=mid)
	   return Find_max(2*t+1,l,r);
   else
   {
       SegTree ans1=Find_max(2*t,l,mid);
	   SegTree ans2=Find_max(2*t+1,mid,r);
	   SegTree ans;
	   ans.max_l=max(ans1.max_l,sum[mid-1]-sum[l-1]+ans2.max_l);
	   ans.max_r=max(ans2.max_r,sum[r-1]-sum[mid-1]+ans1.max_r);
	   ans.max_s=max(max(ans.max_l,ans.max_r),max(ans1.max_s,ans2.max_s));
	   ans.max_s=max(ans.max_s,ans1.max_r+ans2.max_l);
	   return ans;
   }
}

int main()
{
	int a,b;
    while(scanf("%d %d %d",&n,&m,&c)!=EOF)
	{
       for(int i=1;i<=n;i++)
		   scanf("%d",&x[i]);
	   for(int i=1;i<=n-1;i++)
		   scanf("%d",&p[i]);

	   Build(1,1,n);
	   sum[0]=0.0;
       for(int i=2;i<=n;i++)
	   {
          s[i-1]=(x[i]-x[i-1])/2.0-p[i-1]/100.0*c;
		  sum[i-1]=sum[i-2]+s[i-1];
	   }
	   Adjust(1,1,n);
	   double ans=0;
	   for(int i=1;i<=m;i++)
	   {
		   scanf("%d %d",&a,&b);
		   SegTree temp=Find_max(1,a,b);
		   if(temp.max_s>0)
			   ans+=temp.max_s;
	   }
       printf("%.6f\n",ans);
	}
	return 0;
}


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章