2163. 【2017.7.12普及】算法学习 (File IO): input:sfxx.in output:sfxx.out时间限制: 1000 ms 空间限制: 262144 KB 具体限制 题目描述 自从学习了动态规划后,Famer KXP对动态规划的热爱便一发不可收拾,每天都想找点题做,一天,他找到了一道题,但是不会做,于是,他找到了你。题目如下: 给出N个无序不重复的数,再有M个询问,每次询问一个数是否在那N个数中,若在,则ans增加2^K,K为该数在原数列中的位置。由于ans过大,所以只要求你输出ans mod 10^9+7。输入第一行,两个数N,M,第二行N个数,第三行M个数。输出 输出最终答案。样例输入5 51 3 4 6 51 8 1 3 6样例输出24 数据范围限制30% 0《N,M《10050% 0,N,M《10000100% 0《N,M《100000输入的数均在2^31 以内解: 这题快速幂加二分查找。 也可以打表加二分,反正都是满分。打表需要打完所有的可能;既2的100以内的次方。快速幂就是一种神奇的算法。。。
var
l,r,n,i,j,m,mid,p,ans:longint;
a:array[1..100000,1..2] of longint;
s:array[0..100000] of longint;procedure qsort(x,y:longint);var
i,j,mid: longint;
t:array[1..2] of longint;begin
i:=x;
j:=y;
mid:=a[x,1];
repeat
while mid<a[j,1] do dec(j);
while mid>a[i,1] do inc(i);
if i<=j then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i<y then qsort(i,y);
if x<j then qsort(x,j);end;procedure aa;begin
for i:=1 to m do
begin
read(p);
l:=1;
r:=n;
while l<r do
begin
mid:=(l+r) div 2;
if a[mid,1]>=p then r:=mid
else l:=mid+1;
end;
if a[l,1]=p then ans:=(ans+s[a[l,2]]) mod 1000000007;
end;end;begin
assign(input,'sfxx.in');
reset(input);
assign(output,'sfxx.out');
rewrite(output);
readln(n,m);
s[0]:=1;
for i:=1 to n do
begin
read(a[i,1]);
a[i,2]:=i;
s[i]:=(s[i-1]*2) mod 1000000007;
end;
qsort(1,n);
aa;
writeln(ans);end.
本题不提供打表程序(不解释/滑稽)。今天又只写了一题,不过我分享一种算法。并查集: 我应该学过,BUT啦啦啦。我忘了。。 并查集是一种树型的数据结构,用于处理一些不相交集合的合并问题。 (这句话,我承认不是我想的,是复制来的,不过说的很有道理。en); 并查集的主要操作有:
1-合并两个集合
2-查找一个单位;
3-压缩路径。
有三种操作:
1:合并两个集合:
procedure hb(c,p:longint);//两个集合的合并处
var
hong:longint;
lan:longint;
begin
hong:=getfather(c);
lan:=getfather(p); father[hong]:=father(lan);
end;
其实这也不算是完全合并,时间复杂度就省在只更新一个点。 而要注意的是,getfather是一个程序名,Pascal不会自带。
procedure getfather(x:longint);
begin
if father[x]=0 then getfather:=x else begin
getfather:=getfather(father[x]); father[x]:=getfather;
end;
end; 不知道有没有错误,毕竟我才手打出来,(我一定会认真检查程序!/斜眼笑);如果某位大神路过请看看啊啦啦啦。 接着是查找(仅仅判断在不在同一列(呸,好像叫集合吧啦啦)!!!):
function cz(x,y:longint):boolean;
begin
if getfather(x)=getfather(y)
then exit(true) //判断在不在同一个集合里面。 else exit(false); //exit(XXXX)‘xxxx’就是退出时函数所带得值。 end; 大致是这样的。。。。 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
可能排版有问题,因为这个编辑器,咳咳。。。***