[NOIP集训]10月17日

今天的文件夹:10月17日.zip

今天就是测试了,题目还是有难度的。然而,由于这星期的段考、运动会等事,我这几天状态并不好,成绩也不理想。也许过几天会好起来吧。

测试结果:Ranklist

Orz @刘一麟学神

Orz @宋澎玉学神

T1:直接考虑比较困难,我们反着来,计算“美观的”排列个数$F(k)$,其中$1 \leq k \leq n$。根据题意,有$F(1)=2$,$F(2)=4$,对于$3 \leq k \leq n$,有$F(k)=F(k-1)+F(k-2)$。这就是著名的Fibonacci数列的两倍。又因为总排列数为$2^n$,所以最终结果就是$2^n-F(k)$。

其实我在当时并没有严格证明上述性质,而是打表找规律的。现在证明的话,分类讨论就行了。

注意高精度的使用,我计算$2^n$时用了极其低效的倍增法,好在Cena比较快过了,但AYYZVijos上爆内存+超时,还要优化。

T2:脑筋急转弯。题目比较吓人,其实就是按坐标排序后求逆序对数。

T3:容我再想两天……

代码:

  1 program domino;
  2 uses math;
  3 type
  4     bignum=record
  5         data:array[1..10000] of integer;
  6         length:longint;
  7     end;
  8 var
  9     ans:array[1..3] of bignum;
 10     power:array[0..10000] of bignum;
 11     n,i,j,k:longint;
 12     base:bignum;
 13 function init:bignum;
 14 var
 15     num:bignum;
 16 begin
 17     fillchar(num.data,sizeof(num.data),0);
 18     num.length:=1;
 19     exit(num);
 20 end;
 21 function addbignum(x,y:bignum):bignum;
 22 var
 23     ls:bignum;
 24     i:integer;
 25 begin
 26     ls:=init;
 27     ls.length:=max(x.length,y.length);
 28     for i:=1 to ls.length do
 29         ls.data[i]:=x.data[i]+y.data[i];
 30     for i:=1 to ls.length do
 31     begin
 32         ls.data[i+1]:=ls.data[i+1]+ls.data[i] div 10;
 33         ls.data[i]:=ls.data[i] mod 10;
 34     end;
 35     if ls.data[ls.length+1]>0 then
 36         inc(ls.length);
 37     exit(ls);
 38 end;
 39 function minbignum(x,y:bignum):bignum;
 40 var
 41     ls:bignum;
 42     i:integer;
 43 begin
 44     ls:=init;
 45     ls.length:=x.length;
 46     for i:=1 to ls.length do
 47         ls.data[i]:=x.data[i]-y.data[i];
 48     for i:=1 to ls.length do
 49     begin
 50         if ls.data[i]<0 then
 51         begin
 52             ls.data[i]:=ls.data[i]+10;
 53             dec(ls.data[i+1]);
 54         end;
 55     end;
 56     while (ls.data[ls.length]=0)and(ls.length>=1) do
 57         dec(ls.length);
 58     if ls.length=0 then
 59         ls.length:=1;
 60     exit(ls);
 61 end;
 62 function mulbignum(x,y:bignum):bignum;
 63 var
 64     ls:bignum;
 65     i:integer;
 66 begin
 67     ls:=init;
 68     ls.length:=x.length+y.length-1;
 69     for i:=1 to x.length do
 70         for j:=1 to y.length do
 71             ls.data[i+j-1]:=x.data[i]+y.data[j];
 72     for i:=1 to ls.length do
 73     begin
 74         ls.data[i+1]:=ls.data[i+1]+ls.data[i] div 10;
 75         ls.data[i]:=ls.data[i] mod 10;
 76     end;
 77     if ls.data[ls.length+1]>0 then
 78         inc(ls.length);
 79     exit(ls);
 80 end;
 81 function quickpower(k:longint):bignum;
 82 var
 83     ls:bignum;
 84 begin
 85     ls:=init;
 86     if k=0 then
 87         exit(base);
 88     if k=1 then
 89     begin
 90         ls.length:=1;
 91         ls.data[1]:=2;
 92         exit(ls);
 93     end;
 94     ls:=quickpower(k div 2);
 95     if k mod 2=0 then
 96         exit(mulbignum(ls,ls))
 97     else
 98         exit(mulbignum(ls,mulbignum(ls,addbignum(base,base))));
 99 end;
100 begin
101     assign(input,'domino.in');
102     reset(input);
103     assign(output,'domino.out');
104     rewrite(output);
105     readln(n);
106     if n<=2 then
107     begin
108         writeln(0);
109         close(input);
110         close(output);
111         halt;
112     end;
113     fillchar(base,sizeof(base),0);
114     base.data[1]:=1;
115     base.length:=1;
116     power[0]:=base;
117     for i:=1 to n do
118         power[i]:=addbignum(power[i-1],power[i-1]);
119     for i:=1 to 2 do
120             ans[i]:=power[i];
121     for i:=3 to n do
122     begin
123         ans[3]:=addbignum(ans[1],ans[2]);
124         ans[1]:=ans[2];
125         ans[2]:=ans[3];
126     end;
127     base:=power[n];
128             base:=minbignum(base,ans[3]);
129     for i:=base.length downto 1 do
130         write(base.data[i]);
131     writeln;
132     close(input);
133     close(output);
134 end.
domino.pas
 1 program overtaking;
 2 type
 3     car=record
 4         x,y:longint;
 5     end;
 6 var
 7     cars,ls:array[1..300000] of car;
 8     n,i,j:longint;
 9     sum:int64;
10 procedure qsort(l,r:longint);
11 var
12     i,j,ls:longint;
13     p,q:car;
14 begin
15     i:=l;
16     j:=r;
17     p:=cars[(l+r) div 2];
18     repeat
19         while cars[i].x<p.x do
20             inc(i);
21         while cars[j].x>p.x do
22             dec(j);
23         if i<=j then
24         begin
25             q:=cars[i];
26             cars[i]:=cars[j];
27             cars[j]:=q;
28             inc(i);
29             dec(j);
30         end;
31     until i>j;
32     if l<j then
33         qsort(l,j);
34     if i<r then
35         qsort(i,r);
36 end;
37 function exmerge(l,r:longint):int64;
38 var
39   i,j,mid:longint;
40   cnt:longint;
41   sum:int64;
42 begin
43   if l=r then exit(0);
44   mid:=(l+r) div 2;
45   sum:=exmerge(l,mid)+exmerge(mid+1,r);
46   i:=l; j:=mid+1;
47   cnt:=0;
48   while cnt<r-l+1 do
49   begin
50     if cars[i].y<=cars[j].y then
51     begin
52       inc(cnt);
53       ls[cnt]:=cars[i];
54       inc(i);
55     end
56     else
57     begin
58       inc(cnt);
59       ls[cnt]:=cars[j];
60       inc(j);
61       sum:=sum+(mid-i+1);
62     end;
63     if i>mid then
64     begin
65       for j:=j to r do
66       begin
67         inc(cnt);
68         ls[cnt]:=cars[j];
69       end;
70     end;
71     if j>r then
72     begin
73       for i:=i to mid do
74       begin
75         inc(cnt);
76         ls[cnt]:=cars[i];
77       end;
78     end;
79   end;
80   for i:=l to r do
81     cars[i]:=ls[i-l+1];
82   exit(sum);
83 end;
84 begin
85     assign(input,'overtaking.in');
86     reset(input);
87     assign(output,'overtaking.out');
88     rewrite(output);
89     readln(n);
90     for i:=1 to n do
91         readln(cars[i].x,cars[i].y);
92     qsort(1,n);
93     sum:=exmerge(1,n);
94     writeln(sum);
95     close(input);
96     close(output);
97 end.
overtaking.pas

转载于:https://www.cnblogs.com/changke/p/4889924.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值