20190719

T1三分法:

题目描述

如题,给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减。试求出x的值。

输入输出格式

输入格式:
 

第一行一次包含一个正整数N和两个实数l、r,含义如题目描述所示。

第二行包含N+1个实数,从高到低依次表示该N次函数各项的系数。

输出格式:
 

输出为一行,包含一个实数,即为x的值。四舍五入保留5位小数。

输入输出样例

输入样例#1: 复制

3 -0.9981 0.5

1 -3 -3 1

输出样例#1: 复制

-0.41421

说明

时空限制:50ms,128M

数据规模:

对于100%的数据:7<=N<=13

样例说明:

https://cdn.luogu.org/upload/pic/2297.png

如图所示,红色段即为该函数f(x)=x^3-3x^2-3x+1在区间[-0.9981,0.5]上的图像。

当x=-0.41421时图像位于最高点,故此时函数在[l,x]上单调增,[x,r]上单调减,故x=-0.41421,输出-0.41421。

(Tip.l&r的范围并不是非常大ww不会超过一位数)

#include<bits/stdc++.h>

using namespace std;

const double eps=1e-7;

int n;

double L,R;

double a[15];

double F(double x)

{

 double sum=0;

 for(int i=n;i>=0;i--)

 sum=sum*x+a[i];

 return sum;

}

int main()

{

 cin>>n>>L>>R;

 for(int i=n;i>=0;i--) cin>>a[i];

 while(fabs(L-R)>=eps)

 {

  double mid=(L+R)/2;

  if(F(mid+eps)>F(mid-eps)) L=mid;

  else R=mid;

 }

 printf("%.5lf",R);

 return 0;

}

T2乘法逆元:

题目背景

这是一道模板题

题目描述

给定n,p求1~n中所有整数在模p意义下的乘法逆元。

输入输出格式

输入格式:
 

一行n,p

输出格式:
 

n行,第i行表示i在模p意义下的逆元。

输入输出样例

输入样例#1: 复制

10 13

输出样例#1: 复制

1

7

9

10

8

11

2

5

3

4

说明

1 \leq n \leq 3 \times 10 ^ 6, n < p < 200005281≤n≤3×106,n<p<20000528

输入保证 pp 为质数。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll inv[10000005],n,p;

inline ll read(){

         ll k=0,f=1;

         char c=getchar();

         for(;!isdigit(c);c=getchar())

           if(c=='-')

             f=-1;

         for(;isdigit(c);c=getchar())

           k=k*10+c-'0';

         return k*f;

}

int main(){

         n=read(),p=read();

         inv[1]=1;

         cout<<1<<endl;

         for(ll i=2;i<=n;i++)

           inv[i]=(p-p/i)*inv[p%i]%p,printf("%lld\n",inv[i]);

}

T3间谍网络:

#include<bits/stdc++.h>

using namespace std;

struct edge{

         int u,v;

};

edge e[20005],newe[20005];

bool zz[3005],v[3005],ky[3005],pd;

queue<int>ns[3005];

int n,p,f[3005],ne[20005],dfn[3005],low[3005],mon[3005],m,tot,now,s[3005],top,newn,bel[3005],rd[3005],pp,mn=1e9,mnmon=1e9,ans,fron[3005],allmn=1e9;

inline int read(){

         int k=0,f=1;

         char c=getchar();

         for(;!isdigit(c);c=getchar())

           if(c=='-')

             f=-1;

         for(;isdigit(c);c=getchar())

                   k=k*10+c-'0';

         return k*f;

}

inline void tarjan(int x){

         s[++top]=x;

         v[x]=true;

         dfn[x]=low[x]=++now;

         for(int i=f[x];i;i=ne[i]){

                   int y=e[i].v;

                   if(!dfn[y]){

                            tarjan(y);

                            low[x]=min(low[x],low[y]);

                   }

                   else if(dfn[y]&&v[y])

                     low[x]=min(low[x],dfn[y]);

         }

         if(low[x]==dfn[x]){

                   newn++;

//               cout<<newn<<":";

                   while(s[top]!=x)

                     v[s[top]]=false,ns[newn].push(s[top]),bel[s[top]]=newn,s[top]=0,top--;

                   s[top]=0,top--;

                   bel[x]=newn;

                   v[x]=false;

                   ns[newn].push(x);

//               cout<<x<<endl;

         }

         return;

}

int main(){

         n=read(),p=read();

         for(int i=1;i<=p;i++)

           pp=read(),mon[pp]=read(),ky[pp]=true;

         m=read();

         for(int i=1;i<=m;i++){

                   e[i].u=read();

                   e[i].v=read();

                   ne[i]=f[e[i].u],f[e[i].u]=i;

         }

         for(int i=1;i<=n;i++)

           if(!dfn[i])

             zz[i]=true,fron[++tot]=i,tarjan(i);

         for(int i=1;i<=n;i++){

                   for(int j=f[i];j;j=ne[j]){

                            int y=e[j].v;

//                         cout<<j<<" "<<i<<" "<<y<<" "<<bel[i]<<" "<<bel[y]<<endl;

                            if(bel[y]==bel[i])

                              continue;

                            rd[bel[y]]++;

                   }

         }

         for(int i=1;i<=newn;i++){

                   mnmon=1e9,mn=1e9,pd=false;

                   if(!rd[i]){

                            while(ns[i].front()){

                                     mn=min(mn,ns[i].front());

                                     if(ky[ns[i].front()]){

                                               pd=true;

                                               mnmon=min(mnmon,mon[ns[i].front()]);

                                     }

                                     ns[i].pop();

                            }

                            if(pd)

                              ans+=mnmon;

                            else

                              allmn=min(mn,allmn);

                   }

         }

         if(allmn!=1e9){

                   cout<<"NO"<<endl<<allmn;

                   return 0;

         }

         cout<<"YES"<<endl<<ans;

         return 0;

}

T4[HAOI2006]受欢迎的牛

题目背景

本题测试数据已修复。

题目描述

每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

算出有多少头奶牛可以当明星。

输入输出格式

输入格式:
 

第一行:两个用空格分开的整数:N和M

第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B

输出格式:
 

第一行:单独一个整数,表示明星奶牛的数量

输入输出样例

输入样例#1: 复制

3 3

1 2

2 1

2 3

输出样例#1: 复制

1

说明

只有 3 号奶牛可以做明星

【数据范围】

10%的数据N<=20, M<=50

30%的数据N<=1000,M<=20000

70%的数据N<=5000,M<=50000

100%的数据N<=10000,M<=50000

#include<bits/stdc++.h>

using namespace std;

struct edge{

         int u,v;

}e[100005];

queue<int>ns[10005];

bool v[10005];

int n,m,f[10005],ne[100005],dfn[10005],low[10005],cd[10005],newn,zz[10005],top,s[10005],tot,now,bel[10005],ans,pd;

inline int read(){

         int k=0,f=1;

         char c=getchar();

         for(;!isdigit(c);c=getchar())

           if(c=='-')

             f=-1;

         for(;isdigit(c);c=getchar())

                   k=k*10+c-'0';

         return k*f;

}

inline void tarjan(int x){

         s[++top]=x;

         v[x]=true;

         dfn[x]=low[x]=++now;

         for(int i=f[x];i;i=ne[i]){

                   int y=e[i].v;

                   if(!dfn[y]){

                            tarjan(y);

                            low[x]=min(low[x],low[y]);

                   }

                   else if(dfn[y]&&v[y])

                     low[x]=min(low[x],dfn[y]);

         }

         if(low[x]==dfn[x]){

                   newn++;

                   while(s[top]!=x)

                     v[s[top]]=false,ns[newn].push(s[top]),bel[s[top]]=newn,s[top]=0,top--;

                   s[top]=0,top--;

                   bel[x]=newn;

                   v[x]=false;

                   ns[newn].push(x);

         }

         return;

}

int main(){

         n=read(),m=read();

         for(int i=1;i<=m;i++){

                   e[i].u=read(),e[i].v=read();

                   ne[i]=f[e[i].u],f[e[i].u]=i;

         }

         for(int i=1;i<=n;i++)

           if(!dfn[i])

             zz[++tot]=i,tarjan(i);

         for(int i=1;i<=n;i++){

                   for(int j=f[i];j;j=ne[j]){

                            int y=e[j].v;

                            if(bel[y]==bel[i])

                              continue;

                            cd[bel[i]]++;

                   }

         }

         for(int i=1;i<=n;i++)

           if(!cd[bel[i]]&&!pd)

             ans++,pd=bel[i];

           else if(pd==bel[i]&&!cd[bel[i]])

             ans++;

           else if(pd!=bel[i]&&!cd[bel[i]]){

                cout<<0;

                return 0;

           }

         cout<<ans;

         return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值