2018 FJUT acm校賽 b題 第二集:以後我就叫你小蛤了
阿新 • • 發佈:2018-05-14
else 規律 pan RM 運行時間 std 等於 AI ane
SampleOutput
第二集:以後我就叫你小蛤了
TimeLimit:1000MS MemoryLimit:128MB 64-bit integer IO format:%lld Problem Description"小蛤啊,對了以後我就叫你小蛤了,你給的題完全沒有難度啊"
"哼,你別得意,讓你碰巧做出來了而已,接下來這題你絕對不可能做出來的,你要是做出來了balabalabala...."
"行了行了,快說題目吧,我時間寶貴啊!" 小A心急如焚,想盡快知道小C的消息
"請聽題:
給n個正整數a1,a2,a3,……,an,求所有子區間異或和的異或和。比如{2,4,6}的子區間有{{2},{4},{6},{2,4},{4,6},{2,4,6}}
其中異或是按位異或,即C/C++中的"^"運算符"
"這麽簡單,看我三下五除二解決了這題,三分鐘後你就叫小蛤沒得商量了!你答應給我,告訴我小C的消息可不許反悔!"
"哼,爺蛤蟆大仙是那種會反悔的人嗎,而且你不可能會做這題的,看你一會怎麽給自己找臺階下!"
註意異或有兩個常用的性質(下面的"^"代表異或運算)
-
a^a=0
-
a^0=a
Input
單組數據
開頭是一個整數n代表n個數字,n<=5*105
接下來有n個數a1,a2,a3,……an ,(0<=ai<230)
Output
輸出所有子區間異或和的異或和
SampleInput4 3 3 6 7
0
hint: 所有子區間與對應的異或和如下: {3} 3 {3,3} 0 {3,3,6} 6 {3,3,6,7} 1 {3} 3 {3,6} 5 {3,6,7} 2 {6} 6 {6,7} 1 {7} 7 所以答案=3^0^6^1^3^5^2^6^1^7=0
【思路】:
你可以發現一個規律,第一個位置的數出現的次數為n,第二個位置的數出現的次數為2*(n-1)....到中間位置
比如
1 2 3
3 4 3
1 2 3 4
4 6 6 4
1 2 3 4 5
5 8 9 8 5
紅色為單個位置上的出現個數
然後兩邊對稱,我的思路是先把每個位置的次數打個表。再根據題意給的
-
a^a=0
-
a^0=a
因為如果在這個位置的次數為奇數 的話,肯定等於它本身。
為偶數,肯定等於0
進行有運算後保存,最後再進行一次O(n)的求和。
就可以得到答案了。
貼上代碼(運行時間:40ms)
#include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long ll; ll math[500005]; ll data[500005]; int main() { int n; while(~scanf("%d",&n)) {memset(math,0,sizeof(math)); ll a; ll c=n; ll b=1; int flag=0; if(n%2==0) { a=n/2; } else {a=n/2+1; flag=1; } for(int i=0;i<a;i++) { math[i]=c*(b); b++; c--; } int j; if(flag==0) j=a-1; else j=a-2; for(int i=a;i<n;i++) { math[i]=math[j]; j--; } for(int i=0;i<n;i++) {scanf("%lld",&data[i]); if(math[i]%2==0) data[i]=0; } ll sum=0; for(int i=0;i<n;i++) { sum^=data[i]; } printf("%lld\n",sum); } return 0; }
2018 FJUT acm校賽 b題 第二集:以後我就叫你小蛤了