程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> bzoj 2120 數顏色 題解

bzoj 2120 數顏色 題解

編輯:C++入門知識

【原題】 2120: 數顏色 Time Limit: 6 Sec  Memory Limit: 259 MB Submit: 1201  Solved: 429 [Submit][Status] Description 墨墨購買了一套N支彩色畫筆(其中有些顏色可能相同),擺成一排,你需要回答墨墨的提問。墨墨會像你發布如下指令: 1、 Q L R代表詢問你從第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。 2、 R P Col 把第P支畫筆替換為顏色Col。為了滿足墨墨的要求,你知道你需要干什麼了嗎? Input 第1行兩個整數N,M,分別代表初始畫筆的數量以及墨墨會做的事情的個數。第2行N個整數,分別代表初始畫筆排中第i支畫筆的顏色。第3行到第2+M行,每行分別代表墨墨會做的一件事情,格式見題干部分。 Output 對於每一個Query的詢問,你需要在對應的行中給出一個數字,代表第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。 Sample Input 6 5   1 2 3 4 5 5   Q 1 4   Q 2 6   R 1 2   Q 1 4   Q 2 6   Sample Output 4   4   3   4   HINT 對於100%的數據,N≤10000,M≤10000,修改操作不多於1000次,所有的輸入數據中出現的所有整數均大於等於1且不超過10^6。   【分析】以前用莫隊算法做一直超時。今天意外聽說可以用很神的暴力A過去,於是打算去試試。 【基礎暴力代碼】 [cpp]   #include<cstdio>   #include<cstring>   using namespace std;   bool f[1000005];   int a[10005],l,r,n,m,i,j,ans;   char c;   int main()   {     scanf("%d%d",&n,&m);     for (i=1;i<=n;i++)       scanf("%d",&a[i]);     for (i=1;i<=m;i++)     {       c=' ';while (c!='Q'&&c!='R') c=getchar();       scanf("%d%d",&l,&r);       if (c=='R') {a[l]=r;continue;}       ans=0;memset(f,0,sizeof(f));       for (j=l;j<=r;j++)         if (!f[a[j]]) ans++,f[a[j]]=true;       printf("%d\n",ans);     }     return 0;   }     我們會發現,f數組的MEMSET太耗時間了。怎麼辦呢?用凌神的標號法!做到某個i操作時,從l到r掃描,若f[a[j]]還不是i就把他賦成i,並把ans加一。 可是這樣還是超時啊。事實證明,當數組開得很大時,尋址需要很多時間。 我們可以把顏色離散一下,使每次判重的數組f的元素只有11000(注意會改1000次),這樣2s妥妥地A了。 【代碼】 [cpp]  #include<cstdio>   using namespace std;   int f[11005],l,r,n,m,i,j,ans,p,d[10005];   int a[1000005];   char c;   int main()   {     scanf("%d%d",&n,&m);     for (i=1;i<=n;i++)     {       int o;       scanf("%d",&o);       if (!a[o]) a[o]=++p;       d[i]=a[o];     }     for (i=1;i<=m;i++)     {       c=' ';while (c!='Q'&&c!='R') c=getchar();       scanf("%d%d",&l,&r);       if (c=='R') {if(!a[r])a[r]=++p;d[l]=a[r];continue;}       ans=0;       for (j=l;j<=r;j++)         if (f[d[j]]!=i) ans++,f[d[j]]=i;       printf("%d\n",ans);     }     return 0;   }  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved