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
样例说明:
如图所示,红色段即为该函数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;
}