[4月月赛]

我好像不会做

Description

plw现在在一个仓库里当搬砖工,这个仓库存放的是n种不同颜色的砖块,颜色编号从1-n。plw突然兴起想堆一个墙,为了美观,plw决定按照1-n的颜色编号顺序从下往上垒成一列。

    有一个传送带和仓库相连,传送带按照 a[1] a[2] ... a[n] 的颜色顺序源源不断的送砖进来。

    如果当前送进来的砖恰好是plw所需要的, plw就会把这个砖垒进墙内。否则plw就把这个砖放进一旁的次元栈里面,次元栈可以存放无数个砖。

    每次plw新垒上一个砖后,他会看看次元栈的顶部的砖是不是所需要的(如果次元栈中有砖),如果是他就会从次元栈中取出这个砖,并且垒上去。

    如果plw没办法得到想要的砖,plw就会开启传送带,传送带会送入下一个砖。

    plw想知道他需要至少启动多少次传送带,才能完成目标。

    启动一次传送带会送入一块砖。

PS:

假定plw无限高,身高为 INF.

Input

n <= 1e5

a[1] ... a[n] 为1-n的排列。

output

输出一个数,为需要多少个砖块。

Examples

Input
12
8 9 10 6 5 7 11 3 4 1 2 12

Output

48

正确解法:

开long long

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <set>
 7 #include <map>
 8 #include <vector>
 9 #include <cctype>
10 #include <sstream>
11 using namespace std;
12 typedef long long ll;
13 const int inf=0x7fffffff;
14 const int N=100000+100;
15 const int M=50000+10;
16 const int MOD=998244353;
17 const double PI=acos(-1.0);
18 int n;
19 ll a[N];
20 ll l[N],r[N],b[N],bok[N],ans=0,now=0;
21 int main()
22 {
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++)
25     {
26         scanf("%lld",&a[i]);
27         l[i]=i-1;
28         r[i]=i+1;
29         b[a[i]]=i;
30     }
31     for(int i=1;i<=n;i++)
32     {
33         if(bok[i]==0)
34         {
35             now=i;
36             ans++;
37             for(int pos=b[i];pos<=n;pos=b[now])
38             {
39                 l[pos]=pos-1;
40                 r[pos]=pos+1;
41                 bok[now]=1;
42                 now++;
43                 while(a[l[pos]]==now||a[r[pos]]==now)
44                 {
45                     if(a[l[pos]]==now)
46                     {
47                         l[pos]--;
48                         bok[now]=1;
49                         now++;
50                     }
51                     else
52                     {
53                         r[pos]++;
54                         bok[now]=1;
55                         now++;
56                     }
57                 }
58                 if(b[now]<r[pos])   break;
59             }
60 
61         }
62     }
63     cout<<ans*n-n+b[n]<<endl;
64 
65     return 0;
66 }
View Code

 

 

我好像会做了

Description

初中的wxkgg上课很不认真,终于有一天在数学课上走神被数学老师抓住了,老师让他站起来回答问题,wxkgg支支吾吾答不上来,同桌的独行哥看不下去了,偷偷写好答案在纸条上传给了wxkgg,这才得以脱险。那么上面写的是什么呢? 给定一个三角形坐标,分别将三角形边向外做正方形,同时将相邻正方形的两个相邻角相连,再从三角形三个顶点引出直线垂直于刚才的相连边,试问最后的三条垂线的交点坐标是什么呢?(老实的初中题 做不出来和wxkgg一起反省 :D )

Input

输入三个整数表示三角形三点x1,y1,x2,y2,x3,y3(1<=x,y<=1e9)

output

输出交点坐标,如答案形如P/Q,则答案改为P*Q^-1,并将坐标对1e9+7取模。所有答案均为整数。

Examples

Input
0 0
1 1
2 0

Output

1 333333336

正确解法:

提示

AS1垂直NP,CS2垂直QZ,BS3垂直MR,MNAB、PQCA、BCZR为正方形,ABC为给出三角形,O为所求答案

 

由题可知:这个点是重心,也就是(x1+x2+x3)/3,  (y1+y2+y3)/3;

首先说明逆元的概念,类似于倒数的性质。

方程ax≡1(mod  p),的解称为a关于模p的逆,当gcd(a,p)==1(即a,p互质)时,方程有唯一解,否则无解。

对于一些题目会要求把结果MOD一个数,通常是一个较大的质数,对于加减乘法通过同余定理可以直接拆开计算,

但对于(a/b)%MOD这个式子,是不可以写成(a%MOD/b%MOD)%MOD的,但是可以写为(a*b^-1)%MOD,其中b^-1表示b的逆元。

知道了逆元的作用,接下来就是逆元的求法。

首先,有一个费马小定理:

费马小定理(Fermat's little theorem)数论中的一个重要定理,在1636年提出,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。

意思很明了,由上方的公式很容易推导出:a*a(p-2)≡1(mod p)对于整数a,p,a关于p的逆元就是a^(p-2),直接快速幂解之即可,但注意这个定理要求a,p互质!

 

答案要求 P * Q 的逆元 %MOD , Q的逆元就是 Q的(MOD-2)次方 %MOD;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <set>
 7 #include <map>
 8 #include <vector>
 9 #include <cctype>
10 #include <sstream>
11 using namespace std;
12 typedef long long ll;
13 const int inf=0x7fffffff;
14 const int N=100000+100;
15 const int M=50000+10;
16 const int MOD=1e9+7;
17 const double PI=acos(-1.0);
18 ll xx,yy;
19 ll ans1=0,ans2=0;
20 ll solve(ll a,ll b)
21 {
22     ll r=1;
23     while(b)
24     {
25         if(b%2==1)  r=(r*a)%MOD;
26         b=b>>1;
27         a=(a*a)%MOD;
28     }
29     return r;
30 }
31 int main()
32 {
33     for(int i=1;i<=3;i++)
34     {
35         scanf("%lld %lld",&xx,&yy);
36         ans1+=xx;
37         ans2+=yy;
38     }
39     ll kk=solve(3,MOD-2);
40     if(ans1%3==0)
41         cout<<ans1/3<<" ";
42     else
43     {
44         ans1=(ans1*kk)%MOD;
45         cout<<ans1<<" ";
46     }
47     if(ans2%3==0)
48         cout<<ans2/3<<endl;
49     else
50     {
51         ans2=(ans2*kk)%MOD;
52         cout<<ans2<<endl;
53     }
54 
55     return 0;
56 }
View Code

 

 我能做

Description

duxing201606毕业后子承父业继承了一家公司。在公司中,除了duxing201606以外的员工都有一个上司。如果X是Y的上司,Y是Z的上司,那么Y和Z都是X的下属。

    duxing201606会经常分配任务给员工,duxing201606非常喜欢团队去完成任务,所以每次duxing201606给X分配任务的时候,会同时给X的所有下属都分配这个任务,该任务的编号为X。

    duxing201606想知道如果下达多个命令的话,公司会不会乱套。duxing201606一共会下达3种命令:

    1 x 给员工x和他的下属都分配编号为X的任务。

    2 x 员工x和他的下属都完成了编号为X的任务。

    3 x 输出员工x所有任务中编号最小的那个任务。 如果员工x没有任务就输出-1,否则输出最小的任务编号。

Input

第一行为 n m,代表有n个员工, duxing201606会下达m条命令( 1 <= n, m <= 5e4)。

第二行 n-1个p[i],p[i]代表的是 第 i+1 号员工的上司是谁,(  1<= p[i] <= i)。

第3行到m+2行,每一行输入一个 op x,含义如上。

output

对于每条命令3,输出答案

Examples

Input
9 9
1 2 2 1 5 5 5 8
3 1
3 6
1 5
3 5
3 6
1 1
3 6
2 1
3 6

Output

9 9
1 2 2 1 5 5 5 8
3 1
3 6
1 5
3 5
3 6
1 1
3 6
2 1
3 6

正确解法:

用并查集,如果有任务,就bok[u]=1,任务完成就 bok[u]=0;

然后找这个人有没有任务,就往上级中找,看他们的任务,最后的boss任务特判

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <set>
 7 #include <map>
 8 #include <vector>
 9 #include <cctype>
10 #include <sstream>
11 using namespace std;
12 typedef long long ll;
13 const int inf=0x7fffffff;
14 const int N=50000+100;
15 const int M=50000+10;
16 const int MOD=1e9+7;
17 const double PI=acos(-1.0);
18 int n,m;
19 int fa[N],bok[N];
20 int op,u;
21 int main()
22 {
23     scanf("%d %d",&n,&m);
24     for(int i=1;i<=n;i++)
25         fa[i]=i;
26     for(int i=2;i<=n;i++)
27     {
28         int x;
29         scanf("%d",&x);
30         fa[i]=x;
31     }
32     while(m--)
33     {
34         scanf("%d %d",&op,&u);
35         if(op==1)   bok[u]=1;
36         else if(op==2)  bok[u]=0;
37         else
38         {
39             int ans=inf;
40             while(fa[u]!=u)
41             {
42                 if(bok[u])
43                 {
44                     ans=min(ans,u);
45                 }
46                 u=fa[u];
47             }
48             if(bok[u])
49                 ans=min(ans,u);
50             if(ans==inf)
51                 cout<<-1<<endl;
52             else
53                 cout<<ans<<endl;
54         }
55     }
56 
57     return 0;
58 }
View Code

 

 

转载于:https://www.cnblogs.com/Kaike/p/10870268.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值