滑稽树
(huajitree.pas/c/cpp)
【问题描述】
这是一颗赛艇滑稽树
JZYZ的湖畔边有一棵滑稽树,每年的冬天滑稽树上都会长出很多个滑稽果。我们用一个二维平面N,M描述每个滑稽果所能落下的位置,即每个滑稽果不可能落到我们所描述的二维平面之外。
滑稽大师cdc钟爱于收集滑稽果,但是他只有一个篮子,篮子只能放在一个点上,即一个篮子最多收集一个滑稽果。现在滑稽大师cdc想知道他收集到滑稽果的期望值是多少。(cdc放的篮子在任意位置的概率相同)
为了(zao)方(shu)便(ju)起(fang)见(bian),我们用一个数S描述这个二维平面。
例如:
S=32=(100000)2 ,N=2,M=3
其对应的二维平面为:
100
000
其中1表示滑稽果所落下的位置,即有一个滑稽果落在坐标为(1,1)的位置。
那么这个数据的答案就是 1*(1/(2*3))=1/6
例如:
S=33=(100001)2 ,N=2,M=3
其对应的二维平面为:
100
001
其中1表示滑稽果所落下的位置,即有一个滑稽果落在坐标为(1,1)的位置,有一个在坐标为(2,3)的位置。
那么这个数据的答案就是 1*(2/(2*3))=1/3
【输入】
输入仅为1行三个正整数,分别为N,M,S
【输出】
输出仅一行,为期望值的既约分数。即输出为a/b的形式,其中gcd(a,b)==1
如果期望值为0,输出0即可,如果为1,输出1/1
【输入输出样例1】
huajitree.in |
huajitree.out |
2 3 32 |
1/6 |
【数据范围】
对于70%的数据 N*M<=31 S<=2^31
对于 100%的数据 N*M<=63S<=2^63
题解:
纯模拟,把S拆成二进制查一下有多少个1,然后把这个数和N*M求一下gcd,除一下输出就好了。说求期望值可能对新高一不太友好….
cpp:
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=2333333;
long long m,n,s,sum=0;
long long a[maxn];
long long gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int main()
{
freopen("huajitree.in","r",stdin);
freopen("huajitree.out","w",stdout);
cin>>n>>m>>s;
for(int i=1;;i++)
{
if(s==0)
{
sum=i-1;
break;
}
a[i]=s%2;
s=s/2;
}
int map=n*m;
int ans=0;
for(int i=sum;i>0;i--)
{
if(i>map)
break;
if(i<=map)
{
if(a[i]==1)
ans++;
}
}
//cout<<ans<<endl;
int he=gcd(map,ans);
ans=ans/he;
map=map/he;
if(ans!=0)
cout<<ans<<"/"<<map<<endl;
if(ans==0)
cout<<"0"<<endl;
return 0;
}
背包
(pack.pas/c/cpp)
【问题描述】
滑稽大师cdc依靠每天的辛勤努力,终于收集到了足够多的滑稽,每个滑稽有两个属性,分别是滑稽值h和体积v,他要把所有的滑稽带走,但是cdc只有一个固定容积的背包。怎么才能带走尽可能多的滑稽值呢?
因为cdc是神犇,所以他很轻松的解决了这个问题。现在cdc来到了滑稽工厂,他要把所有的滑稽打包发给各个滑稽销售点,但是每次打包cdc都要付出一定的代价。
我们把滑稽工厂打包滑稽的生产线看作一个一维线段,每个滑稽都是线段上的一个点,且每个滑稽的顺序不可改变。
且每次打包滑稽只能是一段连续的区间,定义这个线段上从左到右第i个点的滑稽值为hi,体积为vi,设每次打包的区间为[i,j],则每次打包的代价为,现在cdc想知道他需要支付的最小代价为多少。他需要支付的代价为打包所有滑稽的代价和。
【输入】
第一行为一个正整数N,表示N个滑稽
接下来的N行每行两个正整数v,h,分别表示体积与滑稽值
【输出】
输出仅一行,表示cdc可能需要支付的最小代价
【输入输出样例1】
pack.in |
pack.out |
4 1 4 2 3 3 2 4 1 |
85 /*分组为{1}{2}{3}{4} 85=4*1+(4+3)*2+(4+3+2)*3+(4+3+2+1)*4 */ |
【数据范围】
对于60%的数据N<=1000
对于100%的数据
N<=1000000
hi,vi<=500
保证答案在long long 范围内
题解:
起名叫pack是为了衔接剧情QAQ,60分裸的DP,会DP就应该会,如果学过DP这个的60分没写出来就应该考虑补一下DP了。
所有数据都是随意的..所以加下一些奇淫技巧也许能暴力A掉?
给出状态转移方程:
首先把h和v的前缀和都搞出来
然后状态转移方程就很显然了:
O(N^2)的样子看来要60分狗带?
不怂,不怂,我们上斜率优化
来回到状态转移方程。
我们♂推♂一♂推
这样子就可以把决策搞出来了,不妨设:
然后我们再设,优于当且仅当
然后就来推吧!
这样子斜率优化的方程就得出来了,单调队列加成就可以A掉此题了。
cpp:
大水题
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=2333333;
long long n,sum[maxn];
long long ans=0;
struct huaji
{
long long v,h;
}hua[maxn];
int main()
{
freopen("pack.in","r",stdin);
freopen("pack.out","w",stdout);
cin>>n;
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
{
cin>>hua[i].v>>hua[i].h;
sum[i]=sum[i-1]+hua[i].h;
}
for(int i=1;i<=n;i++)
{
ans=ans+sum[i]*hua[i].v;
}
cout<<ans<<endl;
return 0;
}
街区运输
block(.pas/c/cpp)
【问题描述】
好的,现在你们已经完美的解决了打包的问题了,现在需要把这些滑稽分发给各个滑稽销售点,
滑稽大师cdc想要把所有的滑稽分发出去,但是每个街区之间的道路有时候会因为各种原因而封闭掉,导致无法运输,cdc可以通过膜法瞬间知道哪些道路封闭了或那些道路又重新开放了(注:一个道路可能会封闭好几次,但是每次开放与之前封闭了几次无关)。他想知道从一个街区到另一个街区是否有可以到达的道路。
每个街区分布在NxM的二维平面上,同时保证N=2,也就是说这个二维平面只有两行M列,其中每个焦点代表一个街区。同时保证每次封闭和重新开放的道路一定在两个相邻的城市之间,在开始时所有的道路都是封闭的。
【输入】
第一行为正整数M,代表这是一个2*M的二维平面。
接下来的若干行,分别有4种形式.
1. Exit:结束输入
2. Openx1 y1 x2 y2 开放(x1,y1)至(x2,y2)的道路
3. Closex1 y1 x2 y2 封闭(x1,y1)至(x2,y2)的道路
//数据保证以上所有的(x1,y1) (x2,y2)在平面上相邻
4. Askx1 y1 x2 y2 询问(x1,y1) (x2,y2)是否存在通路
【输出】
对于每个询问,输出1行,如果存在,请输出Y,如果不存在,请输出N
【输入输出样例1】
block.in |
block.out |
2 Open 1 1 1 2 Open 1 2 2 2 Ask 1 1 2 2 Ask 2 1 2 2 Exit |
Y N |
【数据范围】
对于100%的数据保证N<=1e5所有信息小于1e5
对于30%的数据保证N<=100
对于另外30%的数据保证N<=10000
题解:
我太弱啦出不了第三题,这是BZOJ上的一道题,所以说这个的题解你随便一搜成片的都是,我简单废话一下,本题所需要的数据结构就是线段树,简单的说就是用线段树维护连通性,高二的各位神犇你们说良心不良心呀。
怎么用线段树维护连通性呢?
反正我是用一个线段树里维护6个值,分别是
左上到左下的连通性
左上到右下的连通性
左上到右上的连通性
左下到右下的连通性
左下到右上的连通性
右上到右下的连通性
维护四个值好像也没什么问题,具体的自己思考
然后合并什么的就很好(ma)搞(fan)了
具体的实现可以参考我180行的代码,虽然写的很丑..
当然,本题没有强制在线,分块+并查集随便搞搞也可以过
COGS上有一个神犇90行就解决了,你们也可以去看看他的代码
线段树。
cpp:
#include <iostream> 5 #include <cstring> 6 #include <cstdio> 7 #include <cstdlib> 8 #include <string> 9 #include <ctime> 10 #include <cmath> 11 #include <queue> 12 #include <map> 13 #include <iomanip> 14 #include <algorithm> 15 using namespace std; 16 #define FILE "block" 17 #define ll long long 18 #define up(i,j,n) for(int i=j;i<=n;i++) 19 #define down(i,j,n) for(int i=j;i>=n;i--) 20 const int MAXN=1e5+5; 21 const int oo=0x3f3f3f3f; 22 inline int read(){ 23 char ch=getchar();int x=0,f=1; 24 while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} 25 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 26 return x*f; 27 } 28 struct Tree{ 29 bool luru;/*left up to right up*/ 30 bool ldrd;/*left down to right down*/ 31 bool lurd;/*left up to right down*/ 32 bool ldru;/*left down to right up*/ 33 bool luld;/*left up ro left down*/ 34 bool rurd;/*right up to right down*/ 35 }t[MAXN<<4]; 36 bool toright[2][MAXN],pipe[MAXN]; 37 int N,r1,c1,r2,c2,k,v,limleft,limright,cnt=0; 38 char s[20]; 39 namespace solution{ 40 Tree reload(Tree a,Tree b,bool upedge,bool downedge){ 41 Tree c; 42 c.luld=a.luld;c.rurd=b.rurd; 43 c.luru=(a.luru&upedge&b.luru)|(a.lurd&downedge&b.ldru); 44 c.ldrd=(a.ldrd&downedge&b.ldrd)|(a.ldru&upedge&b.lurd); 45 c.lurd=(c.luru&c.rurd)|(c.luld&c.ldrd)|(a.luru&upedge&b.lurd)|(a.lurd&downedge&b.ldrd); 46 c.ldru=(c.ldrd&c.rurd)|(c.luld&c.luru)|(a.ldrd&downedge&b.ldru)|(a.ldru&upedge&b.luru); 47 c.luld=c.luld|(c.lurd&c.ldrd)|(c.ldru&c.luru)|(a.luru&upedge&b.luld&downedge&a.ldrd); 48 c.rurd=c.rurd|(c.lurd&c.luru)|(c.ldru&c.ldrd)|(b.luru&upedge&a.rurd&downedge&b.ldrd); 49 return c; 50 } 51 void build(int leftt,int rightt,int root){ 52 if(leftt==rightt){ 53 t[root].luru=t[root].ldrd=1; 54 t[root].lurd=t[root].ldru=t[root].luld=t[root].rurd=0; 55 return; 56 } 57 int mid=(leftt+rightt)>>1; 58 t[root].luru=t[root].ldrd=t[root].lurd=t[root].ldru=t[root].luld=t[root].rurd=0; 59 build(leftt,mid,root<<1); 60 build(mid+1,rightt,root<<1|1); 61 } 62 void updata1(int leftt,int rightt,int root){ 63 if(leftt>k||rightt<k) return; 64 if(leftt==k&&rightt==k){ 65 t[root].luld=t[root].rurd=t[root].lurd=t[root].ldru=v; 66 return; 67 } 68 int mid=(leftt+rightt)>>1; 69 updata1(leftt,mid,root<<1); 70 updata1(mid+1,rightt,root<<1|1); 71 t[root]=reload(t[root<<1],t[root<<1|1],toright[0][mid],toright[1][mid]); 72 } 73 void updata2(int leftt,int rightt,int root){ 74 if(leftt>k||rightt<k) return; 75 if(leftt==k&&rightt==k) return; 76 int mid=(leftt+rightt)>>1; 77 updata2(leftt,mid,root<<1); 78 updata2(mid+1,rightt,root<<1|1); 79 t[root]=reload(t[root<<1],t[root<<1|1],toright[0][mid],toright[1][mid]); 80 } 81 Tree get(int leftt,int rightt,int root){ 82 Tree a,b,c; 83 if(leftt>=limleft&&rightt<=limright) return t[root]; 84 int mid=(leftt+rightt)>>1; 85 if(mid+1<=limleft) return get(mid+1,rightt,root<<1|1); 86 else if(limright<=mid) return get(leftt,mid,root<<1); 87 else{ 88 a=get(leftt,mid,root<<1); 89 b=get(mid+1,rightt,root<<1|1); 90 c=reload(a,b,toright[0][mid],toright[1][mid]); 91 } 92 return c; 93 } 94 void slove(){ 95 memset(toright,0,sizeof(toright)); 96 while(scanf("%s",s)!=EOF){ 97 if(s[0]=='E')break; 98 if(s[0]=='O'){ 99 c1=read();r1=read();c2=read();r2=read(); 100 if(r1==r2&&c1!=c2){ 101 k=r1;v=1;pipe[k]=1; 102 updata1(1,N,1); 103 } 104 if(r1!=r2&&c1==c2){ 105 r1=min(r1,r2);k=r1; 106 toright[c1-1][r1]=1; 107 updata2(1,N,1); 108 } 109 } 110 if(s[0]=='C'){ 111 c1=read();r1=read();c2=read();r2=read(); 112 if(r1>r2){ 113 swap(r1,r2); 114 swap(c1,c2); 115 }/*make sure that r1<=r2*/ 116 if(r1==r2&&c1!=c2){ 117 k=r1;v=0;pipe[k]=0; 118 updata1(1,N,1); 119 } 120 if(r1!=r2&&c1==c2){ 121 r1=min(r1,r2); 122 toright[c1-1][r1]=0;k=r1; 123 updata2(1,N,1); 124 } 125 } 126 if(s[0]=='A'){ 127 c1=read();r1=read();c2=read();r2=read(); 128 if(c1==c2&&r1==r2){puts("Y");continue;} 129 if(r1>r2){ 130 swap(r1,r2); 131 swap(c1,c2); 132 }/*make sure that r1<=r2*/ 133 limleft=1;limright=r1;Tree go_left=get(1,N,1); 134 limleft=r1;limright=r2;Tree go_mid=get(1,N,1); 135 limleft=r2;limright=N;Tree go_right=get(1,N,1); 136 if(r1==r2&&c1!=c2){ 137 if(go_left.rurd||go_right.luld||go_mid.luld)puts("Y"); 138 else puts("N"); 139 } 140 if(r1!=r2&&c1==c2){ 141 if(c1==1){ 142 if((go_left.rurd&go_mid.ldrd&go_right.luld)||go_mid.luru||(go_left.rurd&go_mid.ldru)||(go_right.luld&go_mid.lurd))puts("Y"); 143 else puts("N"); 144 }else{ 145 if((go_left.rurd&go_mid.luru&go_right.luld)||go_mid.ldrd||(go_left.rurd&go_mid.lurd)||(go_right.luld&go_mid.ldru))puts("Y"); 146 else puts("N"); 147 } 148 } 149 if(r1!=r2&&c1!=c2){ 150 if(c1==1){/*left up to right down*/ 151 if((go_left.rurd&go_mid.ldrd)||go_mid.lurd||(go_left.rurd&go_mid.ldru&go_right.luld)||(go_mid.luru&go_right.luld))puts("Y"); 152 else puts("N"); 153 }else{/*left down to right up*/ 154 if((go_left.rurd&go_mid.luru)||go_mid.ldru||(go_left.rurd&go_mid.lurd&go_right.luld)||(go_mid.ldrd&go_right.luld))puts("Y"); 155 else puts("N"); 156 } 157 } 158 } 159 } 160 } 161 } 162 int main(){ 163 freopen(FILE".in","r",stdin); 164 freopen(FILE".out","w",stdout); 165 using namespace solution; 166 N=read(); 167 build(1,N,1); 168 slove(); 169 return 0; 170 }