मैं एक समस्या जो कुछ इस तरह है हल करने के लिए कोशिश कर रहा हूँ पर टीएलई पारित करने के लिए:सुझाव Spoj
मैं दिया हूँ n संख्या (1 < = n < = 10^5) .मैं अपने बाईं ओर सभी संख्याओं का योग लिखना है जो वर्तमान संख्या से छोटे हैं और सभी एन संख्याओं के लिए प्रक्रिया दोहराएं। फिर मुझे पहले प्राप्त प्राप्त राशि का योग मिलना होगा। (प्रत्येक संख्या एन, 0 < = एन < = 10^6)।
उदाहरण के लिए,
1 5 3 6 4
less1 less5 less3 less6 less4
(0) + (1) + (1)+(1+5+3)+(1+3)
0 + 1 + 1 + 9 + 4
= 15
इस समस्या के लिए एक तुच्छ समाधान दो छोरों को चलाने के लिए किया जाएगा और दिए गए नंबर से प्रत्येक के लिए सभी नंबरों कि संख्या से कम की राशि मिल जाती है और अंत में उन की राशि देना योग आउटपुट के रूप में है। समय जटिलता ओ (एन^2) है।
मुझे लगता है कि बाइनरी इंडेक्सेड ट्री (फेनविक ट्री) का उपयोग करके इस समस्या के लिए एक बेहतर ओ (nlogn) समाधान है। प्रत्येक नंबर के लिए मैं प्रत्येक संख्या को वैश्विक सरणी में जोड़ दूंगा और बीआईटी के दो स्पष्ट संचालन करूँगा। मुझे लगता है कि इस एल्गोरिदम की समय जटिलता ओ (nlogn) है जो सत्य पिछले ओ (एन) से स्पष्ट रूप से बेहतर है^2)।
मैंने कोड को ++ में लागू किया है।
#include<iostream>
#include<cstdio>
using namespace std;
#define max 1000001
long int a[max];
void add(long int v,int idx){
while(idx<max){
a[idx] += v;
idx += (idx & -idx);
}
}
long int sum(int idx){
long int s=0;
while(idx>0){
s += a[idx];
idx -= (idx & -idx);
}
return s;
}
int main()
{
int t;
scanf("%d",&t);
for(int w=0;w<t;w++){
int n;
scanf("%d",&n);
for(int i=0;i<max;i++)
a[i]=0;
int arr[n];
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
long long res=0;
for(int i=0;i<n;i++){
if(arr[i]!=0){
add(arr[i],arr[i]);
res += (sum(arr[i]-1));
}
}
printf("%lld\n",res);
}
return 0;
}
मैं दो प्रश्न हैं:
पहले, मैं यह सही कर रहा हूँ?/क्या मेरा तर्क सही है?
दूसरा, अगर मैं समय जटिलता के बारे में सही हूं तो ओ (nlogn) होने के बाद यह धीमा क्यों चलता है? क्या आप किसी और अनुकूलन के साथ मेरी मदद कर सकते हैं?
1.41 सेकंड के साथ स्वीकार्य हो गया। साथ ही मैंने अपना आखिरी स्वीकृत कोड अपडेट किया है। अनुकूलन के लिए कोई सुझाव?
टिप्पणियों के आधार पर मैं तेजी आई/ओ के लिए अपने खुद के समारोह की कोशिश की, लेकिन अभी भी यह मेरी है.यह नहीं हो रहा है तेजी से आई/ओ के लिए मेरे समारोह है:
inline int read(){
char c=getchar_unlocked();
int n=0;
while(!(c>='0' && c<='9'))
c=getchar_unlocked();
while(c>='0' && c<='9'){
n=n*10 + (c-'0');
c=getchar_unlocked();
}
return n;
}
यह समस्या के लिए लिंक है :
http://www.spoj.pl/problems/DCEPC206/
अगर ऐसा कोई है जो इसे हल करने विकलांगों है, तो कृपया मुझे बताएं। धन्यवाद।
क्या आप एक उदाहरण प्रदान कर सकते हैं? उदाहरण के लिए, '5 2 3 9 6 4' के लिए अपेक्षित आउटपुट क्या है? – IVlad
@IVlad: मैंने teh प्रश्न संपादित किया है और इसके लिए एक उदाहरण दिया है। आपके इनपुट के लिए बीटीडब्ल्यू मेरा कोड 27 देता है। –
यह अभी भी अस्पष्ट नहीं है। क्या आप चरण-दर-चरण उदाहरण दे सकते हैं? – zvrba